OSDN Git Service

am 00db0826: am 203b4354: Merge "Revert "[DO NOT MERGE] Bump up the timeout for uncry...
[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 org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35 import android.Manifest;
36 import android.app.AppOpsManager;
37 import android.app.ApplicationThreadNative;
38 import android.app.IActivityContainer;
39 import android.app.IActivityContainerCallback;
40 import android.app.IAppTask;
41 import android.app.ITaskStackListener;
42 import android.app.ProfilerInfo;
43 import android.app.admin.DevicePolicyManager;
44 import android.app.usage.UsageEvents;
45 import android.app.usage.UsageStatsManagerInternal;
46 import android.appwidget.AppWidgetManager;
47 import android.content.res.Resources;
48 import android.graphics.Bitmap;
49 import android.graphics.Point;
50 import android.graphics.Rect;
51 import android.os.BatteryStats;
52 import android.os.PersistableBundle;
53 import android.os.storage.IMountService;
54 import android.os.storage.StorageManager;
55 import android.service.voice.IVoiceInteractionSession;
56 import android.util.ArrayMap;
57 import android.util.ArraySet;
58 import android.util.SparseIntArray;
59
60 import android.view.Display;
61 import com.android.internal.R;
62 import com.android.internal.annotations.GuardedBy;
63 import com.android.internal.app.IAppOpsService;
64 import com.android.internal.app.IVoiceInteractor;
65 import com.android.internal.app.ProcessMap;
66 import com.android.internal.app.ProcessStats;
67 import com.android.internal.os.BackgroundThread;
68 import com.android.internal.os.BatteryStatsImpl;
69 import com.android.internal.os.ProcessCpuTracker;
70 import com.android.internal.os.TransferPipe;
71 import com.android.internal.os.Zygote;
72 import com.android.internal.util.FastPrintWriter;
73 import com.android.internal.util.FastXmlSerializer;
74 import com.android.internal.util.MemInfoReader;
75 import com.android.internal.util.Preconditions;
76 import com.android.server.AppOpsService;
77 import com.android.server.AttributeCache;
78 import com.android.server.IntentResolver;
79 import com.android.server.LocalServices;
80 import com.android.server.ServiceThread;
81 import com.android.server.SystemService;
82 import com.android.server.SystemServiceManager;
83 import com.android.server.Watchdog;
84 import com.android.server.am.ActivityStack.ActivityState;
85 import com.android.server.firewall.IntentFirewall;
86 import com.android.server.pm.Installer;
87 import com.android.server.pm.UserManagerService;
88 import com.android.server.statusbar.StatusBarManagerInternal;
89 import com.android.server.wm.AppTransition;
90 import com.android.server.wm.WindowManagerService;
91 import com.google.android.collect.Lists;
92 import com.google.android.collect.Maps;
93
94 import libcore.io.IoUtils;
95 import libcore.util.EmptyArray;
96
97 import org.xmlpull.v1.XmlPullParser;
98 import org.xmlpull.v1.XmlPullParserException;
99 import org.xmlpull.v1.XmlSerializer;
100
101 import android.app.Activity;
102 import android.app.ActivityManager;
103 import android.app.ActivityManager.RunningTaskInfo;
104 import android.app.ActivityManager.StackInfo;
105 import android.app.ActivityManagerInternal;
106 import android.app.ActivityManagerNative;
107 import android.app.ActivityOptions;
108 import android.app.ActivityThread;
109 import android.app.AlertDialog;
110 import android.app.AppGlobals;
111 import android.app.ApplicationErrorReport;
112 import android.app.Dialog;
113 import android.app.IActivityController;
114 import android.app.IApplicationThread;
115 import android.app.IInstrumentationWatcher;
116 import android.app.INotificationManager;
117 import android.app.IProcessObserver;
118 import android.app.IServiceConnection;
119 import android.app.IStopUserCallback;
120 import android.app.IUiAutomationConnection;
121 import android.app.IUserSwitchObserver;
122 import android.app.Instrumentation;
123 import android.app.Notification;
124 import android.app.NotificationManager;
125 import android.app.PendingIntent;
126 import android.app.backup.IBackupManager;
127 import android.content.ActivityNotFoundException;
128 import android.content.BroadcastReceiver;
129 import android.content.ClipData;
130 import android.content.ComponentCallbacks2;
131 import android.content.ComponentName;
132 import android.content.ContentProvider;
133 import android.content.ContentResolver;
134 import android.content.Context;
135 import android.content.DialogInterface;
136 import android.content.IContentProvider;
137 import android.content.IIntentReceiver;
138 import android.content.IIntentSender;
139 import android.content.Intent;
140 import android.content.IntentFilter;
141 import android.content.IntentSender;
142 import android.content.pm.ActivityInfo;
143 import android.content.pm.ApplicationInfo;
144 import android.content.pm.ConfigurationInfo;
145 import android.content.pm.IPackageDataObserver;
146 import android.content.pm.IPackageManager;
147 import android.content.pm.InstrumentationInfo;
148 import android.content.pm.PackageInfo;
149 import android.content.pm.PackageManager;
150 import android.content.pm.ParceledListSlice;
151 import android.content.pm.UserInfo;
152 import android.content.pm.PackageManager.NameNotFoundException;
153 import android.content.pm.PathPermission;
154 import android.content.pm.ProviderInfo;
155 import android.content.pm.ResolveInfo;
156 import android.content.pm.ServiceInfo;
157 import android.content.res.CompatibilityInfo;
158 import android.content.res.Configuration;
159 import android.net.Proxy;
160 import android.net.ProxyInfo;
161 import android.net.Uri;
162 import android.os.Binder;
163 import android.os.Build;
164 import android.os.Bundle;
165 import android.os.Debug;
166 import android.os.DropBoxManager;
167 import android.os.Environment;
168 import android.os.FactoryTest;
169 import android.os.FileObserver;
170 import android.os.FileUtils;
171 import android.os.Handler;
172 import android.os.IBinder;
173 import android.os.IPermissionController;
174 import android.os.IProcessInfoService;
175 import android.os.IRemoteCallback;
176 import android.os.IUserManager;
177 import android.os.Looper;
178 import android.os.Message;
179 import android.os.Parcel;
180 import android.os.ParcelFileDescriptor;
181 import android.os.PowerManagerInternal;
182 import android.os.Process;
183 import android.os.RemoteCallbackList;
184 import android.os.RemoteException;
185 import android.os.SELinux;
186 import android.os.ServiceManager;
187 import android.os.StrictMode;
188 import android.os.SystemClock;
189 import android.os.SystemProperties;
190 import android.os.UpdateLock;
191 import android.os.UserHandle;
192 import android.os.UserManager;
193 import android.provider.Settings;
194 import android.text.format.DateUtils;
195 import android.text.format.Time;
196 import android.util.AtomicFile;
197 import android.util.EventLog;
198 import android.util.Log;
199 import android.util.Pair;
200 import android.util.PrintWriterPrinter;
201 import android.util.Slog;
202 import android.util.SparseArray;
203 import android.util.TimeUtils;
204 import android.util.Xml;
205 import android.view.Gravity;
206 import android.view.LayoutInflater;
207 import android.view.View;
208 import android.view.WindowManager;
209
210 import dalvik.system.VMRuntime;
211
212 import java.io.BufferedInputStream;
213 import java.io.BufferedOutputStream;
214 import java.io.DataInputStream;
215 import java.io.DataOutputStream;
216 import java.io.File;
217 import java.io.FileDescriptor;
218 import java.io.FileInputStream;
219 import java.io.FileNotFoundException;
220 import java.io.FileOutputStream;
221 import java.io.IOException;
222 import java.io.InputStreamReader;
223 import java.io.PrintWriter;
224 import java.io.StringWriter;
225 import java.lang.ref.WeakReference;
226 import java.util.ArrayList;
227 import java.util.Arrays;
228 import java.util.Collections;
229 import java.util.Comparator;
230 import java.util.HashMap;
231 import java.util.HashSet;
232 import java.util.Iterator;
233 import java.util.List;
234 import java.util.Locale;
235 import java.util.Map;
236 import java.util.Set;
237 import java.util.concurrent.atomic.AtomicBoolean;
238 import java.util.concurrent.atomic.AtomicLong;
239
240 public final class ActivityManagerService extends ActivityManagerNative
241         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
242
243     private static final String USER_DATA_DIR = "/data/user/";
244     // File that stores last updated system version and called preboot receivers
245     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
246
247     static final String TAG = "ActivityManager";
248     static final String TAG_MU = "ActivityManagerServiceMU";
249     static final boolean DEBUG = false;
250     static final boolean localLOGV = DEBUG;
251     static final boolean DEBUG_BACKUP = localLOGV || false;
252     static final boolean DEBUG_BROADCAST = localLOGV || false;
253     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
254     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
255     static final boolean DEBUG_CLEANUP = localLOGV || false;
256     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
257     static final boolean DEBUG_FOCUS = false;
258     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
259     static final boolean DEBUG_MU = localLOGV || false;
260     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
261     static final boolean DEBUG_LRU = localLOGV || false;
262     static final boolean DEBUG_PAUSE = localLOGV || false;
263     static final boolean DEBUG_POWER = localLOGV || false;
264     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
265     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
266     static final boolean DEBUG_PROCESSES = localLOGV || false;
267     static final boolean DEBUG_PROVIDER = localLOGV || false;
268     static final boolean DEBUG_RESULTS = localLOGV || false;
269     static final boolean DEBUG_SERVICE = localLOGV || false;
270     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
271     static final boolean DEBUG_STACK = localLOGV || false;
272     static final boolean DEBUG_SWITCH = localLOGV || false;
273     static final boolean DEBUG_TASKS = localLOGV || false;
274     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
275     static final boolean DEBUG_TRANSITION = localLOGV || false;
276     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
277     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
278     static final boolean DEBUG_VISBILITY = localLOGV || false;
279     static final boolean DEBUG_PSS = localLOGV || false;
280     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
281     static final boolean DEBUG_RECENTS = localLOGV || false;
282     static final boolean VALIDATE_TOKENS = false;
283     static final boolean SHOW_ACTIVITY_START_TIME = true;
284
285     // Control over CPU and battery monitoring.
286     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
287     static final boolean MONITOR_CPU_USAGE = true;
288     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
289     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
290     static final boolean MONITOR_THREAD_CPU_USAGE = false;
291
292     // The flags that are set for all calls we make to the package manager.
293     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
294
295     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
296
297     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
298
299     // Maximum number recent bitmaps to keep in memory.
300     static final int MAX_RECENT_BITMAPS = 3;
301
302     // Amount of time after a call to stopAppSwitches() during which we will
303     // prevent further untrusted switches from happening.
304     static final long APP_SWITCH_DELAY_TIME = 5*1000;
305
306     // How long we wait for a launched process to attach to the activity manager
307     // before we decide it's never going to come up for real.
308     static final int PROC_START_TIMEOUT = 10*1000;
309
310     // How long we wait for a launched process to attach to the activity manager
311     // before we decide it's never going to come up for real, when the process was
312     // started with a wrapper for instrumentation (such as Valgrind) because it
313     // could take much longer than usual.
314     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
315
316     // How long to wait after going idle before forcing apps to GC.
317     static final int GC_TIMEOUT = 5*1000;
318
319     // The minimum amount of time between successive GC requests for a process.
320     static final int GC_MIN_INTERVAL = 60*1000;
321
322     // The minimum amount of time between successive PSS requests for a process.
323     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
324
325     // The minimum amount of time between successive PSS requests for a process
326     // when the request is due to the memory state being lowered.
327     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
328
329     // The rate at which we check for apps using excessive power -- 15 mins.
330     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
331
332     // The minimum sample duration we will allow before deciding we have
333     // enough data on wake locks to start killing things.
334     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335
336     // The minimum sample duration we will allow before deciding we have
337     // enough data on CPU usage to start killing things.
338     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
339
340     // How long we allow a receiver to run before giving up on it.
341     static final int BROADCAST_FG_TIMEOUT = 10*1000;
342     static final int BROADCAST_BG_TIMEOUT = 60*1000;
343
344     // How long we wait until we timeout on key dispatching.
345     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
346
347     // How long we wait until we timeout on key dispatching during instrumentation.
348     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
349
350     // Amount of time we wait for observers to handle a user switch before
351     // giving up on them and unfreezing the screen.
352     static final int USER_SWITCH_TIMEOUT = 2*1000;
353
354     // Maximum number of users we allow to be running at a time.
355     static final int MAX_RUNNING_USERS = 3;
356
357     // How long to wait in getAssistContextExtras for the activity and foreground services
358     // to respond with the result.
359     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
360
361     // Maximum number of persisted Uri grants a package is allowed
362     static final int MAX_PERSISTED_URI_GRANTS = 128;
363
364     static final int MY_PID = Process.myPid();
365
366     static final String[] EMPTY_STRING_ARRAY = new String[0];
367
368     // How many bytes to write into the dropbox log before truncating
369     static final int DROPBOX_MAX_SIZE = 256 * 1024;
370
371     // Access modes for handleIncomingUser.
372     static final int ALLOW_NON_FULL = 0;
373     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
374     static final int ALLOW_FULL_ONLY = 2;
375
376     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
377
378     // Delay in notifying task stack change listeners (in millis)
379     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
380
381     // Necessary ApplicationInfo flags to mark an app as persistent
382     private static final int PERSISTENT_MASK =
383             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
384
385     /** All system services */
386     SystemServiceManager mSystemServiceManager;
387
388     private Installer mInstaller;
389
390     /** Run all ActivityStacks through this */
391     ActivityStackSupervisor mStackSupervisor;
392
393     /** Task stack change listeners. */
394     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
395             new RemoteCallbackList<ITaskStackListener>();
396
397     public IntentFirewall mIntentFirewall;
398
399     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
400     // default actuion automatically.  Important for devices without direct input
401     // devices.
402     private boolean mShowDialogs = true;
403
404     BroadcastQueue mFgBroadcastQueue;
405     BroadcastQueue mBgBroadcastQueue;
406     // Convenient for easy iteration over the queues. Foreground is first
407     // so that dispatch of foreground broadcasts gets precedence.
408     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
409
410     BroadcastQueue broadcastQueueForIntent(Intent intent) {
411         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
412         if (DEBUG_BACKGROUND_BROADCAST) {
413             Slog.i(TAG, "Broadcast intent " + intent + " on "
414                     + (isFg ? "foreground" : "background")
415                     + " queue");
416         }
417         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
418     }
419
420     /**
421      * Activity we have told the window manager to have key focus.
422      */
423     ActivityRecord mFocusedActivity = null;
424
425     /**
426      * List of intents that were used to start the most recent tasks.
427      */
428     ArrayList<TaskRecord> mRecentTasks;
429     ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
430
431     /**
432      * For addAppTask: cached of the last activity component that was added.
433      */
434     ComponentName mLastAddedTaskComponent;
435
436     /**
437      * For addAppTask: cached of the last activity uid that was added.
438      */
439     int mLastAddedTaskUid;
440
441     /**
442      * For addAppTask: cached of the last ActivityInfo that was added.
443      */
444     ActivityInfo mLastAddedTaskActivity;
445
446     public class PendingAssistExtras extends Binder implements Runnable {
447         public final ActivityRecord activity;
448         public final Bundle extras;
449         public final Intent intent;
450         public final String hint;
451         public final int userHandle;
452         public boolean haveResult = false;
453         public Bundle result = null;
454         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
455                 String _hint, int _userHandle) {
456             activity = _activity;
457             extras = _extras;
458             intent = _intent;
459             hint = _hint;
460             userHandle = _userHandle;
461         }
462         @Override
463         public void run() {
464             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
465             synchronized (this) {
466                 haveResult = true;
467                 notifyAll();
468             }
469         }
470     }
471
472     final ArrayList<PendingAssistExtras> mPendingAssistExtras
473             = new ArrayList<PendingAssistExtras>();
474
475     /**
476      * Process management.
477      */
478     final ProcessList mProcessList = new ProcessList();
479
480     /**
481      * All of the applications we currently have running organized by name.
482      * The keys are strings of the application package name (as
483      * returned by the package manager), and the keys are ApplicationRecord
484      * objects.
485      */
486     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
487
488     /**
489      * Tracking long-term execution of processes to look for abuse and other
490      * bad app behavior.
491      */
492     final ProcessStatsService mProcessStats;
493
494     /**
495      * The currently running isolated processes.
496      */
497     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
498
499     /**
500      * Counter for assigning isolated process uids, to avoid frequently reusing the
501      * same ones.
502      */
503     int mNextIsolatedProcessUid = 0;
504
505     /**
506      * The currently running heavy-weight process, if any.
507      */
508     ProcessRecord mHeavyWeightProcess = null;
509
510     /**
511      * The last time that various processes have crashed.
512      */
513     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
514
515     /**
516      * Information about a process that is currently marked as bad.
517      */
518     static final class BadProcessInfo {
519         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
520             this.time = time;
521             this.shortMsg = shortMsg;
522             this.longMsg = longMsg;
523             this.stack = stack;
524         }
525
526         final long time;
527         final String shortMsg;
528         final String longMsg;
529         final String stack;
530     }
531
532     /**
533      * Set of applications that we consider to be bad, and will reject
534      * incoming broadcasts from (which the user has no control over).
535      * Processes are added to this set when they have crashed twice within
536      * a minimum amount of time; they are removed from it when they are
537      * later restarted (hopefully due to some user action).  The value is the
538      * time it was added to the list.
539      */
540     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
541
542     /**
543      * All of the processes we currently have running organized by pid.
544      * The keys are the pid running the application.
545      *
546      * <p>NOTE: This object is protected by its own lock, NOT the global
547      * activity manager lock!
548      */
549     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
550
551     /**
552      * All of the processes that have been forced to be foreground.  The key
553      * is the pid of the caller who requested it (we hold a death
554      * link on it).
555      */
556     abstract class ForegroundToken implements IBinder.DeathRecipient {
557         int pid;
558         IBinder token;
559     }
560     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
561
562     /**
563      * List of records for processes that someone had tried to start before the
564      * system was ready.  We don't start them at that point, but ensure they
565      * are started by the time booting is complete.
566      */
567     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
568
569     /**
570      * List of persistent applications that are in the process
571      * of being started.
572      */
573     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
574
575     /**
576      * Processes that are being forcibly torn down.
577      */
578     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
579
580     /**
581      * List of running applications, sorted by recent usage.
582      * The first entry in the list is the least recently used.
583      */
584     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
585
586     /**
587      * Where in mLruProcesses that the processes hosting activities start.
588      */
589     int mLruProcessActivityStart = 0;
590
591     /**
592      * Where in mLruProcesses that the processes hosting services start.
593      * This is after (lower index) than mLruProcessesActivityStart.
594      */
595     int mLruProcessServiceStart = 0;
596
597     /**
598      * List of processes that should gc as soon as things are idle.
599      */
600     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
601
602     /**
603      * Processes we want to collect PSS data from.
604      */
605     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
606
607     /**
608      * Last time we requested PSS data of all processes.
609      */
610     long mLastFullPssTime = SystemClock.uptimeMillis();
611
612     /**
613      * If set, the next time we collect PSS data we should do a full collection
614      * with data from native processes and the kernel.
615      */
616     boolean mFullPssPending = false;
617
618     /**
619      * This is the process holding what we currently consider to be
620      * the "home" activity.
621      */
622     ProcessRecord mHomeProcess;
623
624     /**
625      * This is the process holding the activity the user last visited that
626      * is in a different process from the one they are currently in.
627      */
628     ProcessRecord mPreviousProcess;
629
630     /**
631      * The time at which the previous process was last visible.
632      */
633     long mPreviousProcessVisibleTime;
634
635     /**
636      * Which uses have been started, so are allowed to run code.
637      */
638     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
639
640     /**
641      * LRU list of history of current users.  Most recently current is at the end.
642      */
643     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
644
645     /**
646      * Constant array of the users that are currently started.
647      */
648     int[] mStartedUserArray = new int[] { 0 };
649
650     /**
651      * Registered observers of the user switching mechanics.
652      */
653     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
654             = new RemoteCallbackList<IUserSwitchObserver>();
655
656     /**
657      * Currently active user switch.
658      */
659     Object mCurUserSwitchCallback;
660
661     /**
662      * Packages that the user has asked to have run in screen size
663      * compatibility mode instead of filling the screen.
664      */
665     final CompatModePackages mCompatModePackages;
666
667     /**
668      * Set of IntentSenderRecord objects that are currently active.
669      */
670     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
671             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
672
673     /**
674      * Fingerprints (hashCode()) of stack traces that we've
675      * already logged DropBox entries for.  Guarded by itself.  If
676      * something (rogue user app) forces this over
677      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
678      */
679     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
680     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
681
682     /**
683      * Strict Mode background batched logging state.
684      *
685      * The string buffer is guarded by itself, and its lock is also
686      * used to determine if another batched write is already
687      * in-flight.
688      */
689     private final StringBuilder mStrictModeBuffer = new StringBuilder();
690
691     /**
692      * Keeps track of all IIntentReceivers that have been registered for
693      * broadcasts.  Hash keys are the receiver IBinder, hash value is
694      * a ReceiverList.
695      */
696     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
697             new HashMap<IBinder, ReceiverList>();
698
699     /**
700      * Resolver for broadcast intents to registered receivers.
701      * Holds BroadcastFilter (subclass of IntentFilter).
702      */
703     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
704             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
705         @Override
706         protected boolean allowFilterResult(
707                 BroadcastFilter filter, List<BroadcastFilter> dest) {
708             IBinder target = filter.receiverList.receiver.asBinder();
709             for (int i=dest.size()-1; i>=0; i--) {
710                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
711                     return false;
712                 }
713             }
714             return true;
715         }
716
717         @Override
718         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
719             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
720                     || userId == filter.owningUserId) {
721                 return super.newResult(filter, match, userId);
722             }
723             return null;
724         }
725
726         @Override
727         protected BroadcastFilter[] newArray(int size) {
728             return new BroadcastFilter[size];
729         }
730
731         @Override
732         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
733             return packageName.equals(filter.packageName);
734         }
735     };
736
737     /**
738      * State of all active sticky broadcasts per user.  Keys are the action of the
739      * sticky Intent, values are an ArrayList of all broadcasted intents with
740      * that action (which should usually be one).  The SparseArray is keyed
741      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
742      * for stickies that are sent to all users.
743      */
744     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
745             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
746
747     final ActiveServices mServices;
748
749     final static class Association {
750         final int mSourceUid;
751         final String mSourceProcess;
752         final int mTargetUid;
753         final ComponentName mTargetComponent;
754         final String mTargetProcess;
755
756         int mCount;
757         long mTime;
758
759         int mNesting;
760         long mStartTime;
761
762         Association(int sourceUid, String sourceProcess, int targetUid,
763                 ComponentName targetComponent, String targetProcess) {
764             mSourceUid = sourceUid;
765             mSourceProcess = sourceProcess;
766             mTargetUid = targetUid;
767             mTargetComponent = targetComponent;
768             mTargetProcess = targetProcess;
769         }
770     }
771
772     /**
773      * When service association tracking is enabled, this is all of the associations we
774      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
775      * -> association data.
776      */
777     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
778             mAssociations = new SparseArray<>();
779     boolean mTrackingAssociations;
780
781     /**
782      * Backup/restore process management
783      */
784     String mBackupAppName = null;
785     BackupRecord mBackupTarget = null;
786
787     final ProviderMap mProviderMap;
788
789     /**
790      * List of content providers who have clients waiting for them.  The
791      * application is currently being launched and the provider will be
792      * removed from this list once it is published.
793      */
794     final ArrayList<ContentProviderRecord> mLaunchingProviders
795             = new ArrayList<ContentProviderRecord>();
796
797     /**
798      * File storing persisted {@link #mGrantedUriPermissions}.
799      */
800     private final AtomicFile mGrantFile;
801
802     /** XML constants used in {@link #mGrantFile} */
803     private static final String TAG_URI_GRANTS = "uri-grants";
804     private static final String TAG_URI_GRANT = "uri-grant";
805     private static final String ATTR_USER_HANDLE = "userHandle";
806     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
807     private static final String ATTR_TARGET_USER_ID = "targetUserId";
808     private static final String ATTR_SOURCE_PKG = "sourcePkg";
809     private static final String ATTR_TARGET_PKG = "targetPkg";
810     private static final String ATTR_URI = "uri";
811     private static final String ATTR_MODE_FLAGS = "modeFlags";
812     private static final String ATTR_CREATED_TIME = "createdTime";
813     private static final String ATTR_PREFIX = "prefix";
814
815     /**
816      * Global set of specific {@link Uri} permissions that have been granted.
817      * This optimized lookup structure maps from {@link UriPermission#targetUid}
818      * to {@link UriPermission#uri} to {@link UriPermission}.
819      */
820     @GuardedBy("this")
821     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
822             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
823
824     public static class GrantUri {
825         public final int sourceUserId;
826         public final Uri uri;
827         public boolean prefix;
828
829         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
830             this.sourceUserId = sourceUserId;
831             this.uri = uri;
832             this.prefix = prefix;
833         }
834
835         @Override
836         public int hashCode() {
837             int hashCode = 1;
838             hashCode = 31 * hashCode + sourceUserId;
839             hashCode = 31 * hashCode + uri.hashCode();
840             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
841             return hashCode;
842         }
843
844         @Override
845         public boolean equals(Object o) {
846             if (o instanceof GrantUri) {
847                 GrantUri other = (GrantUri) o;
848                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
849                         && prefix == other.prefix;
850             }
851             return false;
852         }
853
854         @Override
855         public String toString() {
856             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
857             if (prefix) result += " [prefix]";
858             return result;
859         }
860
861         public String toSafeString() {
862             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
863             if (prefix) result += " [prefix]";
864             return result;
865         }
866
867         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
868             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
869                     ContentProvider.getUriWithoutUserId(uri), false);
870         }
871     }
872
873     CoreSettingsObserver mCoreSettingsObserver;
874
875     /**
876      * Thread-local storage used to carry caller permissions over through
877      * indirect content-provider access.
878      */
879     private class Identity {
880         public final IBinder token;
881         public final int pid;
882         public final int uid;
883
884         Identity(IBinder _token, int _pid, int _uid) {
885             token = _token;
886             pid = _pid;
887             uid = _uid;
888         }
889     }
890
891     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
892
893     /**
894      * All information we have collected about the runtime performance of
895      * any user id that can impact battery performance.
896      */
897     final BatteryStatsService mBatteryStatsService;
898
899     /**
900      * Information about component usage
901      */
902     UsageStatsManagerInternal mUsageStatsService;
903
904     /**
905      * Information about and control over application operations
906      */
907     final AppOpsService mAppOpsService;
908
909     /**
910      * Save recent tasks information across reboots.
911      */
912     final TaskPersister mTaskPersister;
913
914     /**
915      * Current configuration information.  HistoryRecord objects are given
916      * a reference to this object to indicate which configuration they are
917      * currently running in, so this object must be kept immutable.
918      */
919     Configuration mConfiguration = new Configuration();
920
921     /**
922      * Current sequencing integer of the configuration, for skipping old
923      * configurations.
924      */
925     int mConfigurationSeq = 0;
926
927     /**
928      * Hardware-reported OpenGLES version.
929      */
930     final int GL_ES_VERSION;
931
932     /**
933      * List of initialization arguments to pass to all processes when binding applications to them.
934      * For example, references to the commonly used services.
935      */
936     HashMap<String, IBinder> mAppBindArgs;
937
938     /**
939      * Temporary to avoid allocations.  Protected by main lock.
940      */
941     final StringBuilder mStringBuilder = new StringBuilder(256);
942
943     /**
944      * Used to control how we initialize the service.
945      */
946     ComponentName mTopComponent;
947     String mTopAction = Intent.ACTION_MAIN;
948     String mTopData;
949     boolean mProcessesReady = false;
950     boolean mSystemReady = false;
951     boolean mBooting = false;
952     boolean mCallFinishBooting = false;
953     boolean mBootAnimationComplete = false;
954     boolean mWaitingUpdate = false;
955     boolean mDidUpdate = false;
956     boolean mOnBattery = false;
957     boolean mLaunchWarningShown = false;
958
959     Context mContext;
960
961     int mFactoryTest;
962
963     boolean mCheckedForSetup;
964
965     /**
966      * The time at which we will allow normal application switches again,
967      * after a call to {@link #stopAppSwitches()}.
968      */
969     long mAppSwitchesAllowedTime;
970
971     /**
972      * This is set to true after the first switch after mAppSwitchesAllowedTime
973      * is set; any switches after that will clear the time.
974      */
975     boolean mDidAppSwitch;
976
977     /**
978      * Last time (in realtime) at which we checked for power usage.
979      */
980     long mLastPowerCheckRealtime;
981
982     /**
983      * Last time (in uptime) at which we checked for power usage.
984      */
985     long mLastPowerCheckUptime;
986
987     /**
988      * Set while we are wanting to sleep, to prevent any
989      * activities from being started/resumed.
990      */
991     private boolean mSleeping = false;
992
993     /**
994      * Set while we are running a voice interaction.  This overrides
995      * sleeping while it is active.
996      */
997     private boolean mRunningVoice = false;
998
999     /**
1000      * State of external calls telling us if the device is awake or asleep.
1001      */
1002     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1003
1004     static final int LOCK_SCREEN_HIDDEN = 0;
1005     static final int LOCK_SCREEN_LEAVING = 1;
1006     static final int LOCK_SCREEN_SHOWN = 2;
1007     /**
1008      * State of external call telling us if the lock screen is shown.
1009      */
1010     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1011
1012     /**
1013      * Set if we are shutting down the system, similar to sleeping.
1014      */
1015     boolean mShuttingDown = false;
1016
1017     /**
1018      * Current sequence id for oom_adj computation traversal.
1019      */
1020     int mAdjSeq = 0;
1021
1022     /**
1023      * Current sequence id for process LRU updating.
1024      */
1025     int mLruSeq = 0;
1026
1027     /**
1028      * Keep track of the non-cached/empty process we last found, to help
1029      * determine how to distribute cached/empty processes next time.
1030      */
1031     int mNumNonCachedProcs = 0;
1032
1033     /**
1034      * Keep track of the number of cached hidden procs, to balance oom adj
1035      * distribution between those and empty procs.
1036      */
1037     int mNumCachedHiddenProcs = 0;
1038
1039     /**
1040      * Keep track of the number of service processes we last found, to
1041      * determine on the next iteration which should be B services.
1042      */
1043     int mNumServiceProcs = 0;
1044     int mNewNumAServiceProcs = 0;
1045     int mNewNumServiceProcs = 0;
1046
1047     /**
1048      * Allow the current computed overall memory level of the system to go down?
1049      * This is set to false when we are killing processes for reasons other than
1050      * memory management, so that the now smaller process list will not be taken as
1051      * an indication that memory is tighter.
1052      */
1053     boolean mAllowLowerMemLevel = false;
1054
1055     /**
1056      * The last computed memory level, for holding when we are in a state that
1057      * processes are going away for other reasons.
1058      */
1059     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1060
1061     /**
1062      * The last total number of process we have, to determine if changes actually look
1063      * like a shrinking number of process due to lower RAM.
1064      */
1065     int mLastNumProcesses;
1066
1067     /**
1068      * The uptime of the last time we performed idle maintenance.
1069      */
1070     long mLastIdleTime = SystemClock.uptimeMillis();
1071
1072     /**
1073      * Total time spent with RAM that has been added in the past since the last idle time.
1074      */
1075     long mLowRamTimeSinceLastIdle = 0;
1076
1077     /**
1078      * If RAM is currently low, when that horrible situation started.
1079      */
1080     long mLowRamStartTime = 0;
1081
1082     /**
1083      * For reporting to battery stats the current top application.
1084      */
1085     private String mCurResumedPackage = null;
1086     private int mCurResumedUid = -1;
1087
1088     /**
1089      * For reporting to battery stats the apps currently running foreground
1090      * service.  The ProcessMap is package/uid tuples; each of these contain
1091      * an array of the currently foreground processes.
1092      */
1093     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1094             = new ProcessMap<ArrayList<ProcessRecord>>();
1095
1096     /**
1097      * This is set if we had to do a delayed dexopt of an app before launching
1098      * it, to increase the ANR timeouts in that case.
1099      */
1100     boolean mDidDexOpt;
1101
1102     /**
1103      * Set if the systemServer made a call to enterSafeMode.
1104      */
1105     boolean mSafeMode;
1106
1107     /**
1108      * If true, we are running under a test environment so will sample PSS from processes
1109      * much more rapidly to try to collect better data when the tests are rapidly
1110      * running through apps.
1111      */
1112     boolean mTestPssMode = false;
1113
1114     String mDebugApp = null;
1115     boolean mWaitForDebugger = false;
1116     boolean mDebugTransient = false;
1117     String mOrigDebugApp = null;
1118     boolean mOrigWaitForDebugger = false;
1119     boolean mAlwaysFinishActivities = false;
1120     IActivityController mController = null;
1121     String mProfileApp = null;
1122     ProcessRecord mProfileProc = null;
1123     String mProfileFile;
1124     ParcelFileDescriptor mProfileFd;
1125     int mSamplingInterval = 0;
1126     boolean mAutoStopProfiler = false;
1127     int mProfileType = 0;
1128     String mOpenGlTraceApp = null;
1129
1130     final long[] mTmpLong = new long[1];
1131
1132     static class ProcessChangeItem {
1133         static final int CHANGE_ACTIVITIES = 1<<0;
1134         static final int CHANGE_PROCESS_STATE = 1<<1;
1135         int changes;
1136         int uid;
1137         int pid;
1138         int processState;
1139         boolean foregroundActivities;
1140     }
1141
1142     final RemoteCallbackList<IProcessObserver> mProcessObservers
1143             = new RemoteCallbackList<IProcessObserver>();
1144     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1145
1146     final ArrayList<ProcessChangeItem> mPendingProcessChanges
1147             = new ArrayList<ProcessChangeItem>();
1148     final ArrayList<ProcessChangeItem> mAvailProcessChanges
1149             = new ArrayList<ProcessChangeItem>();
1150
1151     /**
1152      * Runtime CPU use collection thread.  This object's lock is used to
1153      * perform synchronization with the thread (notifying it to run).
1154      */
1155     final Thread mProcessCpuThread;
1156
1157     /**
1158      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1159      * Must acquire this object's lock when accessing it.
1160      * NOTE: this lock will be held while doing long operations (trawling
1161      * through all processes in /proc), so it should never be acquired by
1162      * any critical paths such as when holding the main activity manager lock.
1163      */
1164     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1165             MONITOR_THREAD_CPU_USAGE);
1166     final AtomicLong mLastCpuTime = new AtomicLong(0);
1167     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1168
1169     long mLastWriteTime = 0;
1170
1171     /**
1172      * Used to retain an update lock when the foreground activity is in
1173      * immersive mode.
1174      */
1175     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1176
1177     /**
1178      * Set to true after the system has finished booting.
1179      */
1180     boolean mBooted = false;
1181
1182     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1183     int mProcessLimitOverride = -1;
1184
1185     WindowManagerService mWindowManager;
1186
1187     final ActivityThread mSystemThread;
1188
1189     // Holds the current foreground user's id
1190     int mCurrentUserId = 0;
1191     // Holds the target user's id during a user switch
1192     int mTargetUserId = UserHandle.USER_NULL;
1193     // If there are multiple profiles for the current user, their ids are here
1194     // Currently only the primary user can have managed profiles
1195     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1196
1197     /**
1198      * Mapping from each known user ID to the profile group ID it is associated with.
1199      */
1200     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1201
1202     private UserManagerService mUserManager;
1203
1204     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1205         final ProcessRecord mApp;
1206         final int mPid;
1207         final IApplicationThread mAppThread;
1208
1209         AppDeathRecipient(ProcessRecord app, int pid,
1210                 IApplicationThread thread) {
1211             if (localLOGV) Slog.v(
1212                 TAG, "New death recipient " + this
1213                 + " for thread " + thread.asBinder());
1214             mApp = app;
1215             mPid = pid;
1216             mAppThread = thread;
1217         }
1218
1219         @Override
1220         public void binderDied() {
1221             if (localLOGV) Slog.v(
1222                 TAG, "Death received in " + this
1223                 + " for thread " + mAppThread.asBinder());
1224             synchronized(ActivityManagerService.this) {
1225                 appDiedLocked(mApp, mPid, mAppThread, true);
1226             }
1227         }
1228     }
1229
1230     static final int SHOW_ERROR_MSG = 1;
1231     static final int SHOW_NOT_RESPONDING_MSG = 2;
1232     static final int SHOW_FACTORY_ERROR_MSG = 3;
1233     static final int UPDATE_CONFIGURATION_MSG = 4;
1234     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1235     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1236     static final int SERVICE_TIMEOUT_MSG = 12;
1237     static final int UPDATE_TIME_ZONE = 13;
1238     static final int SHOW_UID_ERROR_MSG = 14;
1239     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1240     static final int PROC_START_TIMEOUT_MSG = 20;
1241     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1242     static final int KILL_APPLICATION_MSG = 22;
1243     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1244     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1245     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1246     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1247     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1248     static final int CLEAR_DNS_CACHE_MSG = 28;
1249     static final int UPDATE_HTTP_PROXY_MSG = 29;
1250     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1251     static final int DISPATCH_PROCESSES_CHANGED = 31;
1252     static final int DISPATCH_PROCESS_DIED = 32;
1253     static final int REPORT_MEM_USAGE_MSG = 33;
1254     static final int REPORT_USER_SWITCH_MSG = 34;
1255     static final int CONTINUE_USER_SWITCH_MSG = 35;
1256     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1257     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1258     static final int PERSIST_URI_GRANTS_MSG = 38;
1259     static final int REQUEST_ALL_PSS_MSG = 39;
1260     static final int START_PROFILES_MSG = 40;
1261     static final int UPDATE_TIME = 41;
1262     static final int SYSTEM_USER_START_MSG = 42;
1263     static final int SYSTEM_USER_CURRENT_MSG = 43;
1264     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1265     static final int FINISH_BOOTING_MSG = 45;
1266     static final int START_USER_SWITCH_MSG = 46;
1267     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1268     static final int DISMISS_DIALOG_MSG = 48;
1269     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1270     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1271
1272     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1273     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1274     static final int FIRST_COMPAT_MODE_MSG = 300;
1275     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1276
1277     CompatModeDialog mCompatModeDialog;
1278     long mLastMemUsageReportTime = 0;
1279
1280     /**
1281      * Flag whether the current user is a "monkey", i.e. whether
1282      * the UI is driven by a UI automation tool.
1283      */
1284     private boolean mUserIsMonkey;
1285
1286     /** Flag whether the device has a Recents UI */
1287     boolean mHasRecents;
1288
1289     /** The dimensions of the thumbnails in the Recents UI. */
1290     int mThumbnailWidth;
1291     int mThumbnailHeight;
1292
1293     final ServiceThread mHandlerThread;
1294     final MainHandler mHandler;
1295     final UiHandler mUiHandler;
1296
1297     final class UiHandler extends Handler {
1298         public UiHandler() {
1299             super(com.android.server.UiThread.get().getLooper(), null, true);
1300         }
1301
1302         @Override
1303         public void handleMessage(Message msg) {
1304             switch (msg.what) {
1305             case SHOW_ERROR_MSG: {
1306                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1307                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1308                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1309                 synchronized (ActivityManagerService.this) {
1310                     ProcessRecord proc = (ProcessRecord)data.get("app");
1311                     AppErrorResult res = (AppErrorResult) data.get("result");
1312                     if (proc != null && proc.crashDialog != null) {
1313                         Slog.e(TAG, "App already has crash dialog: " + proc);
1314                         if (res != null) {
1315                             res.set(0);
1316                         }
1317                         return;
1318                     }
1319                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1320                             >= Process.FIRST_APPLICATION_UID
1321                             && proc.pid != MY_PID);
1322                     for (int userId : mCurrentProfileIds) {
1323                         isBackground &= (proc.userId != userId);
1324                     }
1325                     if (isBackground && !showBackground) {
1326                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1327                         if (res != null) {
1328                             res.set(0);
1329                         }
1330                         return;
1331                     }
1332                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1333                         Dialog d = new AppErrorDialog(mContext,
1334                                 ActivityManagerService.this, res, proc);
1335                         d.show();
1336                         proc.crashDialog = d;
1337                     } else {
1338                         // The device is asleep, so just pretend that the user
1339                         // saw a crash dialog and hit "force quit".
1340                         if (res != null) {
1341                             res.set(0);
1342                         }
1343                     }
1344                 }
1345
1346                 ensureBootCompleted();
1347             } break;
1348             case SHOW_NOT_RESPONDING_MSG: {
1349                 synchronized (ActivityManagerService.this) {
1350                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351                     ProcessRecord proc = (ProcessRecord)data.get("app");
1352                     if (proc != null && proc.anrDialog != null) {
1353                         Slog.e(TAG, "App already has anr dialog: " + proc);
1354                         return;
1355                     }
1356
1357                     Intent intent = new Intent("android.intent.action.ANR");
1358                     if (!mProcessesReady) {
1359                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1360                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1361                     }
1362                     broadcastIntentLocked(null, null, intent,
1363                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1364                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1365
1366                     if (mShowDialogs) {
1367                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1368                                 mContext, proc, (ActivityRecord)data.get("activity"),
1369                                 msg.arg1 != 0);
1370                         d.show();
1371                         proc.anrDialog = d;
1372                     } else {
1373                         // Just kill the app if there is no dialog to be shown.
1374                         killAppAtUsersRequest(proc, null);
1375                     }
1376                 }
1377
1378                 ensureBootCompleted();
1379             } break;
1380             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1381                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1382                 synchronized (ActivityManagerService.this) {
1383                     ProcessRecord proc = (ProcessRecord) data.get("app");
1384                     if (proc == null) {
1385                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1386                         break;
1387                     }
1388                     if (proc.crashDialog != null) {
1389                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1390                         return;
1391                     }
1392                     AppErrorResult res = (AppErrorResult) data.get("result");
1393                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1394                         Dialog d = new StrictModeViolationDialog(mContext,
1395                                 ActivityManagerService.this, res, proc);
1396                         d.show();
1397                         proc.crashDialog = d;
1398                     } else {
1399                         // The device is asleep, so just pretend that the user
1400                         // saw a crash dialog and hit "force quit".
1401                         res.set(0);
1402                     }
1403                 }
1404                 ensureBootCompleted();
1405             } break;
1406             case SHOW_FACTORY_ERROR_MSG: {
1407                 Dialog d = new FactoryErrorDialog(
1408                     mContext, msg.getData().getCharSequence("msg"));
1409                 d.show();
1410                 ensureBootCompleted();
1411             } break;
1412             case WAIT_FOR_DEBUGGER_MSG: {
1413                 synchronized (ActivityManagerService.this) {
1414                     ProcessRecord app = (ProcessRecord)msg.obj;
1415                     if (msg.arg1 != 0) {
1416                         if (!app.waitedForDebugger) {
1417                             Dialog d = new AppWaitingForDebuggerDialog(
1418                                     ActivityManagerService.this,
1419                                     mContext, app);
1420                             app.waitDialog = d;
1421                             app.waitedForDebugger = true;
1422                             d.show();
1423                         }
1424                     } else {
1425                         if (app.waitDialog != null) {
1426                             app.waitDialog.dismiss();
1427                             app.waitDialog = null;
1428                         }
1429                     }
1430                 }
1431             } break;
1432             case SHOW_UID_ERROR_MSG: {
1433                 if (mShowDialogs) {
1434                     AlertDialog d = new BaseErrorDialog(mContext);
1435                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1436                     d.setCancelable(false);
1437                     d.setTitle(mContext.getText(R.string.android_system_label));
1438                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1439                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1440                             obtainMessage(DISMISS_DIALOG_MSG, d));
1441                     d.show();
1442                 }
1443             } break;
1444             case SHOW_FINGERPRINT_ERROR_MSG: {
1445                 if (mShowDialogs) {
1446                     AlertDialog d = new BaseErrorDialog(mContext);
1447                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1448                     d.setCancelable(false);
1449                     d.setTitle(mContext.getText(R.string.android_system_label));
1450                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1451                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1452                             obtainMessage(DISMISS_DIALOG_MSG, d));
1453                     d.show();
1454                 }
1455             } break;
1456             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1457                 synchronized (ActivityManagerService.this) {
1458                     ActivityRecord ar = (ActivityRecord) msg.obj;
1459                     if (mCompatModeDialog != null) {
1460                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1461                                 ar.info.applicationInfo.packageName)) {
1462                             return;
1463                         }
1464                         mCompatModeDialog.dismiss();
1465                         mCompatModeDialog = null;
1466                     }
1467                     if (ar != null && false) {
1468                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1469                                 ar.packageName)) {
1470                             int mode = mCompatModePackages.computeCompatModeLocked(
1471                                     ar.info.applicationInfo);
1472                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1473                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1474                                 mCompatModeDialog = new CompatModeDialog(
1475                                         ActivityManagerService.this, mContext,
1476                                         ar.info.applicationInfo);
1477                                 mCompatModeDialog.show();
1478                             }
1479                         }
1480                     }
1481                 }
1482                 break;
1483             }
1484             case START_USER_SWITCH_MSG: {
1485                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1486                 break;
1487             }
1488             case DISMISS_DIALOG_MSG: {
1489                 final Dialog d = (Dialog) msg.obj;
1490                 d.dismiss();
1491                 break;
1492             }
1493             }
1494         }
1495     }
1496
1497     final class MainHandler extends Handler {
1498         public MainHandler(Looper looper) {
1499             super(looper, null, true);
1500         }
1501
1502         @Override
1503         public void handleMessage(Message msg) {
1504             switch (msg.what) {
1505             case UPDATE_CONFIGURATION_MSG: {
1506                 final ContentResolver resolver = mContext.getContentResolver();
1507                 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1508             } break;
1509             case GC_BACKGROUND_PROCESSES_MSG: {
1510                 synchronized (ActivityManagerService.this) {
1511                     performAppGcsIfAppropriateLocked();
1512                 }
1513             } break;
1514             case SERVICE_TIMEOUT_MSG: {
1515                 if (mDidDexOpt) {
1516                     mDidDexOpt = false;
1517                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1518                     nmsg.obj = msg.obj;
1519                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1520                     return;
1521                 }
1522                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1523             } break;
1524             case UPDATE_TIME_ZONE: {
1525                 synchronized (ActivityManagerService.this) {
1526                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1527                         ProcessRecord r = mLruProcesses.get(i);
1528                         if (r.thread != null) {
1529                             try {
1530                                 r.thread.updateTimeZone();
1531                             } catch (RemoteException ex) {
1532                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1533                             }
1534                         }
1535                     }
1536                 }
1537             } break;
1538             case CLEAR_DNS_CACHE_MSG: {
1539                 synchronized (ActivityManagerService.this) {
1540                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1541                         ProcessRecord r = mLruProcesses.get(i);
1542                         if (r.thread != null) {
1543                             try {
1544                                 r.thread.clearDnsCache();
1545                             } catch (RemoteException ex) {
1546                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1547                             }
1548                         }
1549                     }
1550                 }
1551             } break;
1552             case UPDATE_HTTP_PROXY_MSG: {
1553                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1554                 String host = "";
1555                 String port = "";
1556                 String exclList = "";
1557                 Uri pacFileUrl = Uri.EMPTY;
1558                 if (proxy != null) {
1559                     host = proxy.getHost();
1560                     port = Integer.toString(proxy.getPort());
1561                     exclList = proxy.getExclusionListAsString();
1562                     pacFileUrl = proxy.getPacFileUrl();
1563                 }
1564                 synchronized (ActivityManagerService.this) {
1565                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1566                         ProcessRecord r = mLruProcesses.get(i);
1567                         if (r.thread != null) {
1568                             try {
1569                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1570                             } catch (RemoteException ex) {
1571                                 Slog.w(TAG, "Failed to update http proxy for: " +
1572                                         r.info.processName);
1573                             }
1574                         }
1575                     }
1576                 }
1577             } break;
1578             case PROC_START_TIMEOUT_MSG: {
1579                 if (mDidDexOpt) {
1580                     mDidDexOpt = false;
1581                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1582                     nmsg.obj = msg.obj;
1583                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1584                     return;
1585                 }
1586                 ProcessRecord app = (ProcessRecord)msg.obj;
1587                 synchronized (ActivityManagerService.this) {
1588                     processStartTimedOutLocked(app);
1589                 }
1590             } break;
1591             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1592                 synchronized (ActivityManagerService.this) {
1593                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1594                 }
1595             } break;
1596             case KILL_APPLICATION_MSG: {
1597                 synchronized (ActivityManagerService.this) {
1598                     int appid = msg.arg1;
1599                     boolean restart = (msg.arg2 == 1);
1600                     Bundle bundle = (Bundle)msg.obj;
1601                     String pkg = bundle.getString("pkg");
1602                     String reason = bundle.getString("reason");
1603                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1604                             false, UserHandle.USER_ALL, reason);
1605                 }
1606             } break;
1607             case FINALIZE_PENDING_INTENT_MSG: {
1608                 ((PendingIntentRecord)msg.obj).completeFinalize();
1609             } break;
1610             case POST_HEAVY_NOTIFICATION_MSG: {
1611                 INotificationManager inm = NotificationManager.getService();
1612                 if (inm == null) {
1613                     return;
1614                 }
1615
1616                 ActivityRecord root = (ActivityRecord)msg.obj;
1617                 ProcessRecord process = root.app;
1618                 if (process == null) {
1619                     return;
1620                 }
1621
1622                 try {
1623                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1624                     String text = mContext.getString(R.string.heavy_weight_notification,
1625                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1626                     Notification notification = new Notification();
1627                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1628                     notification.when = 0;
1629                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1630                     notification.tickerText = text;
1631                     notification.defaults = 0; // please be quiet
1632                     notification.sound = null;
1633                     notification.vibrate = null;
1634                     notification.color = mContext.getResources().getColor(
1635                             com.android.internal.R.color.system_notification_accent_color);
1636                     notification.setLatestEventInfo(context, text,
1637                             mContext.getText(R.string.heavy_weight_notification_detail),
1638                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1639                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1640                                     new UserHandle(root.userId)));
1641
1642                     try {
1643                         int[] outId = new int[1];
1644                         inm.enqueueNotificationWithTag("android", "android", null,
1645                                 R.string.heavy_weight_notification,
1646                                 notification, outId, root.userId);
1647                     } catch (RuntimeException e) {
1648                         Slog.w(ActivityManagerService.TAG,
1649                                 "Error showing notification for heavy-weight app", e);
1650                     } catch (RemoteException e) {
1651                     }
1652                 } catch (NameNotFoundException e) {
1653                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1654                 }
1655             } break;
1656             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1657                 INotificationManager inm = NotificationManager.getService();
1658                 if (inm == null) {
1659                     return;
1660                 }
1661                 try {
1662                     inm.cancelNotificationWithTag("android", null,
1663                             R.string.heavy_weight_notification,  msg.arg1);
1664                 } catch (RuntimeException e) {
1665                     Slog.w(ActivityManagerService.TAG,
1666                             "Error canceling notification for service", e);
1667                 } catch (RemoteException e) {
1668                 }
1669             } break;
1670             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1671                 synchronized (ActivityManagerService.this) {
1672                     checkExcessivePowerUsageLocked(true);
1673                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1674                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1675                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1676                 }
1677             } break;
1678             case DISPATCH_PROCESSES_CHANGED: {
1679                 dispatchProcessesChanged();
1680                 break;
1681             }
1682             case DISPATCH_PROCESS_DIED: {
1683                 final int pid = msg.arg1;
1684                 final int uid = msg.arg2;
1685                 dispatchProcessDied(pid, uid);
1686                 break;
1687             }
1688             case REPORT_MEM_USAGE_MSG: {
1689                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1690                 Thread thread = new Thread() {
1691                     @Override public void run() {
1692                         reportMemUsage(memInfos);
1693                     }
1694                 };
1695                 thread.start();
1696                 break;
1697             }
1698             case REPORT_USER_SWITCH_MSG: {
1699                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1700                 break;
1701             }
1702             case CONTINUE_USER_SWITCH_MSG: {
1703                 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1704                 break;
1705             }
1706             case USER_SWITCH_TIMEOUT_MSG: {
1707                 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1708                 break;
1709             }
1710             case IMMERSIVE_MODE_LOCK_MSG: {
1711                 final boolean nextState = (msg.arg1 != 0);
1712                 if (mUpdateLock.isHeld() != nextState) {
1713                     if (DEBUG_IMMERSIVE) {
1714                         final ActivityRecord r = (ActivityRecord) msg.obj;
1715                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1716                     }
1717                     if (nextState) {
1718                         mUpdateLock.acquire();
1719                     } else {
1720                         mUpdateLock.release();
1721                     }
1722                 }
1723                 break;
1724             }
1725             case PERSIST_URI_GRANTS_MSG: {
1726                 writeGrantedUriPermissions();
1727                 break;
1728             }
1729             case REQUEST_ALL_PSS_MSG: {
1730                 synchronized (ActivityManagerService.this) {
1731                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1732                 }
1733                 break;
1734             }
1735             case START_PROFILES_MSG: {
1736                 synchronized (ActivityManagerService.this) {
1737                     startProfilesLocked();
1738                 }
1739                 break;
1740             }
1741             case UPDATE_TIME: {
1742                 synchronized (ActivityManagerService.this) {
1743                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1744                         ProcessRecord r = mLruProcesses.get(i);
1745                         if (r.thread != null) {
1746                             try {
1747                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1748                             } catch (RemoteException ex) {
1749                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1750                             }
1751                         }
1752                     }
1753                 }
1754                 break;
1755             }
1756             case SYSTEM_USER_START_MSG: {
1757                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1758                         Integer.toString(msg.arg1), msg.arg1);
1759                 mSystemServiceManager.startUser(msg.arg1);
1760                 break;
1761             }
1762             case SYSTEM_USER_CURRENT_MSG: {
1763                 mBatteryStatsService.noteEvent(
1764                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1765                         Integer.toString(msg.arg2), msg.arg2);
1766                 mBatteryStatsService.noteEvent(
1767                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1768                         Integer.toString(msg.arg1), msg.arg1);
1769                 mSystemServiceManager.switchUser(msg.arg1);
1770                 break;
1771             }
1772             case ENTER_ANIMATION_COMPLETE_MSG: {
1773                 synchronized (ActivityManagerService.this) {
1774                     ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1775                     if (r != null && r.app != null && r.app.thread != null) {
1776                         try {
1777                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1778                         } catch (RemoteException e) {
1779                         }
1780                     }
1781                 }
1782                 break;
1783             }
1784             case FINISH_BOOTING_MSG: {
1785                 if (msg.arg1 != 0) {
1786                     finishBooting();
1787                 }
1788                 if (msg.arg2 != 0) {
1789                     enableScreenAfterBoot();
1790                 }
1791                 break;
1792             }
1793             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1794                 try {
1795                     Locale l = (Locale) msg.obj;
1796                     IBinder service = ServiceManager.getService("mount");
1797                     IMountService mountService = IMountService.Stub.asInterface(service);
1798                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1799                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1800                 } catch (RemoteException e) {
1801                     Log.e(TAG, "Error storing locale for decryption UI", e);
1802                 }
1803                 break;
1804             }
1805             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1806                 synchronized (ActivityManagerService.this) {
1807                     int i = mTaskStackListeners.beginBroadcast();
1808                     while (i > 0) {
1809                         i--;
1810                         try {
1811                             // Make a one-way callback to the listener
1812                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1813                         } catch (RemoteException e){
1814                             // Handled by the RemoteCallbackList
1815                         }
1816                     }
1817                     mTaskStackListeners.finishBroadcast();
1818                 }
1819                 break;
1820             }
1821             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1822                 final int uid = msg.arg1;
1823                 final byte[] firstPacket = (byte[]) msg.obj;
1824
1825                 synchronized (mPidsSelfLocked) {
1826                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1827                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1828                         if (p.uid == uid) {
1829                             try {
1830                                 p.thread.notifyCleartextNetwork(firstPacket);
1831                             } catch (RemoteException ignored) {
1832                             }
1833                         }
1834                     }
1835                 }
1836                 break;
1837             }
1838             }
1839         }
1840     };
1841
1842     static final int COLLECT_PSS_BG_MSG = 1;
1843
1844     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845         @Override
1846         public void handleMessage(Message msg) {
1847             switch (msg.what) {
1848             case COLLECT_PSS_BG_MSG: {
1849                 long start = SystemClock.uptimeMillis();
1850                 MemInfoReader memInfo = null;
1851                 synchronized (ActivityManagerService.this) {
1852                     if (mFullPssPending) {
1853                         mFullPssPending = false;
1854                         memInfo = new MemInfoReader();
1855                     }
1856                 }
1857                 if (memInfo != null) {
1858                     updateCpuStatsNow();
1859                     long nativeTotalPss = 0;
1860                     synchronized (mProcessCpuTracker) {
1861                         final int N = mProcessCpuTracker.countStats();
1862                         for (int j=0; j<N; j++) {
1863                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                 // This is definitely an application process; skip it.
1866                                 continue;
1867                             }
1868                             synchronized (mPidsSelfLocked) {
1869                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                     // This is one of our own processes; skip it.
1871                                     continue;
1872                                 }
1873                             }
1874                             nativeTotalPss += Debug.getPss(st.pid, null, null);
1875                         }
1876                     }
1877                     memInfo.readMemInfo();
1878                     synchronized (ActivityManagerService.this) {
1879                         if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                 + (SystemClock.uptimeMillis()-start) + "ms");
1881                         mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                 memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1884                     }
1885                 }
1886
1887                 int num = 0;
1888                 long[] tmp = new long[1];
1889                 do {
1890                     ProcessRecord proc;
1891                     int procState;
1892                     int pid;
1893                     long lastPssTime;
1894                     synchronized (ActivityManagerService.this) {
1895                         if (mPendingPssProcesses.size() <= 0) {
1896                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1897                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1898                             mPendingPssProcesses.clear();
1899                             return;
1900                         }
1901                         proc = mPendingPssProcesses.remove(0);
1902                         procState = proc.pssProcState;
1903                         lastPssTime = proc.lastPssTime;
1904                         if (proc.thread != null && procState == proc.setProcState
1905                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1906                                         < SystemClock.uptimeMillis()) {
1907                             pid = proc.pid;
1908                         } else {
1909                             proc = null;
1910                             pid = 0;
1911                         }
1912                     }
1913                     if (proc != null) {
1914                         long pss = Debug.getPss(pid, tmp, null);
1915                         synchronized (ActivityManagerService.this) {
1916                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
1917                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1918                                 num++;
1919                                 recordPssSample(proc, procState, pss, tmp[0],
1920                                         SystemClock.uptimeMillis());
1921                             }
1922                         }
1923                     }
1924                 } while (true);
1925             }
1926             }
1927         }
1928     };
1929
1930     public void setSystemProcess() {
1931         try {
1932             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1933             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1934             ServiceManager.addService("meminfo", new MemBinder(this));
1935             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1936             ServiceManager.addService("dbinfo", new DbBinder(this));
1937             if (MONITOR_CPU_USAGE) {
1938                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
1939             }
1940             ServiceManager.addService("permission", new PermissionController(this));
1941             ServiceManager.addService("processinfo", new ProcessInfoService(this));
1942
1943             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1944                     "android", STOCK_PM_FLAGS);
1945             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1946
1947             synchronized (this) {
1948                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1949                 app.persistent = true;
1950                 app.pid = MY_PID;
1951                 app.maxAdj = ProcessList.SYSTEM_ADJ;
1952                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1953                 mProcessNames.put(app.processName, app.uid, app);
1954                 synchronized (mPidsSelfLocked) {
1955                     mPidsSelfLocked.put(app.pid, app);
1956                 }
1957                 updateLruProcessLocked(app, false, null);
1958                 updateOomAdjLocked();
1959             }
1960         } catch (PackageManager.NameNotFoundException e) {
1961             throw new RuntimeException(
1962                     "Unable to find android system package", e);
1963         }
1964     }
1965
1966     public void setWindowManager(WindowManagerService wm) {
1967         mWindowManager = wm;
1968         mStackSupervisor.setWindowManager(wm);
1969     }
1970
1971     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1972         mUsageStatsService = usageStatsManager;
1973     }
1974
1975     public void startObservingNativeCrashes() {
1976         final NativeCrashListener ncl = new NativeCrashListener(this);
1977         ncl.start();
1978     }
1979
1980     public IAppOpsService getAppOpsService() {
1981         return mAppOpsService;
1982     }
1983
1984     static class MemBinder extends Binder {
1985         ActivityManagerService mActivityManagerService;
1986         MemBinder(ActivityManagerService activityManagerService) {
1987             mActivityManagerService = activityManagerService;
1988         }
1989
1990         @Override
1991         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993                     != PackageManager.PERMISSION_GRANTED) {
1994                 pw.println("Permission Denial: can't dump meminfo from from pid="
1995                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996                         + " without permission " + android.Manifest.permission.DUMP);
1997                 return;
1998             }
1999
2000             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2001         }
2002     }
2003
2004     static class GraphicsBinder extends Binder {
2005         ActivityManagerService mActivityManagerService;
2006         GraphicsBinder(ActivityManagerService activityManagerService) {
2007             mActivityManagerService = activityManagerService;
2008         }
2009
2010         @Override
2011         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013                     != PackageManager.PERMISSION_GRANTED) {
2014                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016                         + " without permission " + android.Manifest.permission.DUMP);
2017                 return;
2018             }
2019
2020             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2021         }
2022     }
2023
2024     static class DbBinder extends Binder {
2025         ActivityManagerService mActivityManagerService;
2026         DbBinder(ActivityManagerService activityManagerService) {
2027             mActivityManagerService = activityManagerService;
2028         }
2029
2030         @Override
2031         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033                     != PackageManager.PERMISSION_GRANTED) {
2034                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2035                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036                         + " without permission " + android.Manifest.permission.DUMP);
2037                 return;
2038             }
2039
2040             mActivityManagerService.dumpDbInfo(fd, pw, args);
2041         }
2042     }
2043
2044     static class CpuBinder extends Binder {
2045         ActivityManagerService mActivityManagerService;
2046         CpuBinder(ActivityManagerService activityManagerService) {
2047             mActivityManagerService = activityManagerService;
2048         }
2049
2050         @Override
2051         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053                     != PackageManager.PERMISSION_GRANTED) {
2054                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056                         + " without permission " + android.Manifest.permission.DUMP);
2057                 return;
2058             }
2059
2060             synchronized (mActivityManagerService.mProcessCpuTracker) {
2061                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063                         SystemClock.uptimeMillis()));
2064             }
2065         }
2066     }
2067
2068     public static final class Lifecycle extends SystemService {
2069         private final ActivityManagerService mService;
2070
2071         public Lifecycle(Context context) {
2072             super(context);
2073             mService = new ActivityManagerService(context);
2074         }
2075
2076         @Override
2077         public void onStart() {
2078             mService.start();
2079         }
2080
2081         public ActivityManagerService getService() {
2082             return mService;
2083         }
2084     }
2085
2086     // Note: This method is invoked on the main thread but may need to attach various
2087     // handlers to other threads.  So take care to be explicit about the looper.
2088     public ActivityManagerService(Context systemContext) {
2089         mContext = systemContext;
2090         mFactoryTest = FactoryTest.getMode();
2091         mSystemThread = ActivityThread.currentActivityThread();
2092
2093         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2094
2095         mHandlerThread = new ServiceThread(TAG,
2096                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097         mHandlerThread.start();
2098         mHandler = new MainHandler(mHandlerThread.getLooper());
2099         mUiHandler = new UiHandler();
2100
2101         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102                 "foreground", BROADCAST_FG_TIMEOUT, false);
2103         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104                 "background", BROADCAST_BG_TIMEOUT, true);
2105         mBroadcastQueues[0] = mFgBroadcastQueue;
2106         mBroadcastQueues[1] = mBgBroadcastQueue;
2107
2108         mServices = new ActiveServices(this);
2109         mProviderMap = new ProviderMap(this);
2110
2111         // TODO: Move creation of battery stats service outside of activity manager service.
2112         File dataDir = Environment.getDataDirectory();
2113         File systemDir = new File(dataDir, "system");
2114         systemDir.mkdirs();
2115         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2116         mBatteryStatsService.getActiveStatistics().readLocked();
2117         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118         mOnBattery = DEBUG_POWER ? true
2119                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120         mBatteryStatsService.getActiveStatistics().setCallback(this);
2121
2122         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2123
2124         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2125
2126         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2127
2128         // User 0 is the first and only user that runs at boot.
2129         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2130         mUserLru.add(Integer.valueOf(0));
2131         updateStartedUserArrayLocked();
2132
2133         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2134             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2135
2136         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2137
2138         mConfiguration.setToDefaults();
2139         mConfiguration.locale = Locale.getDefault();
2140
2141         mConfigurationSeq = mConfiguration.seq = 1;
2142         mProcessCpuTracker.init();
2143
2144         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2145         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2146         mStackSupervisor = new ActivityStackSupervisor(this);
2147         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2148
2149         mProcessCpuThread = new Thread("CpuTracker") {
2150             @Override
2151             public void run() {
2152                 while (true) {
2153                     try {
2154                         try {
2155                             synchronized(this) {
2156                                 final long now = SystemClock.uptimeMillis();
2157                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2158                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2159                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2160                                 //        + ", write delay=" + nextWriteDelay);
2161                                 if (nextWriteDelay < nextCpuDelay) {
2162                                     nextCpuDelay = nextWriteDelay;
2163                                 }
2164                                 if (nextCpuDelay > 0) {
2165                                     mProcessCpuMutexFree.set(true);
2166                                     this.wait(nextCpuDelay);
2167                                 }
2168                             }
2169                         } catch (InterruptedException e) {
2170                         }
2171                         updateCpuStatsNow();
2172                     } catch (Exception e) {
2173                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2174                     }
2175                 }
2176             }
2177         };
2178
2179         Watchdog.getInstance().addMonitor(this);
2180         Watchdog.getInstance().addThread(mHandler);
2181     }
2182
2183     public void setSystemServiceManager(SystemServiceManager mgr) {
2184         mSystemServiceManager = mgr;
2185     }
2186
2187     public void setInstaller(Installer installer) {
2188         mInstaller = installer;
2189     }
2190
2191     private void start() {
2192         Process.removeAllProcessGroups();
2193         mProcessCpuThread.start();
2194
2195         mBatteryStatsService.publish(mContext);
2196         mAppOpsService.publish(mContext);
2197         Slog.d("AppOps", "AppOpsService published");
2198         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2199     }
2200
2201     public void initPowerManagement() {
2202         mStackSupervisor.initPowerManagement();
2203         mBatteryStatsService.initPowerManagement();
2204     }
2205
2206     @Override
2207     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2208             throws RemoteException {
2209         if (code == SYSPROPS_TRANSACTION) {
2210             // We need to tell all apps about the system property change.
2211             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2212             synchronized(this) {
2213                 final int NP = mProcessNames.getMap().size();
2214                 for (int ip=0; ip<NP; ip++) {
2215                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2216                     final int NA = apps.size();
2217                     for (int ia=0; ia<NA; ia++) {
2218                         ProcessRecord app = apps.valueAt(ia);
2219                         if (app.thread != null) {
2220                             procs.add(app.thread.asBinder());
2221                         }
2222                     }
2223                 }
2224             }
2225
2226             int N = procs.size();
2227             for (int i=0; i<N; i++) {
2228                 Parcel data2 = Parcel.obtain();
2229                 try {
2230                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2231                 } catch (RemoteException e) {
2232                 }
2233                 data2.recycle();
2234             }
2235         }
2236         try {
2237             return super.onTransact(code, data, reply, flags);
2238         } catch (RuntimeException e) {
2239             // The activity manager only throws security exceptions, so let's
2240             // log all others.
2241             if (!(e instanceof SecurityException)) {
2242                 Slog.wtf(TAG, "Activity Manager Crash", e);
2243             }
2244             throw e;
2245         }
2246     }
2247
2248     void updateCpuStats() {
2249         final long now = SystemClock.uptimeMillis();
2250         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2251             return;
2252         }
2253         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2254             synchronized (mProcessCpuThread) {
2255                 mProcessCpuThread.notify();
2256             }
2257         }
2258     }
2259
2260     void updateCpuStatsNow() {
2261         synchronized (mProcessCpuTracker) {
2262             mProcessCpuMutexFree.set(false);
2263             final long now = SystemClock.uptimeMillis();
2264             boolean haveNewCpuStats = false;
2265
2266             if (MONITOR_CPU_USAGE &&
2267                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2268                 mLastCpuTime.set(now);
2269                 haveNewCpuStats = true;
2270                 mProcessCpuTracker.update();
2271                 //Slog.i(TAG, mProcessCpu.printCurrentState());
2272                 //Slog.i(TAG, "Total CPU usage: "
2273                 //        + mProcessCpu.getTotalCpuPercent() + "%");
2274
2275                 // Slog the cpu usage if the property is set.
2276                 if ("true".equals(SystemProperties.get("events.cpu"))) {
2277                     int user = mProcessCpuTracker.getLastUserTime();
2278                     int system = mProcessCpuTracker.getLastSystemTime();
2279                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
2280                     int irq = mProcessCpuTracker.getLastIrqTime();
2281                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2282                     int idle = mProcessCpuTracker.getLastIdleTime();
2283
2284                     int total = user + system + iowait + irq + softIrq + idle;
2285                     if (total == 0) total = 1;
2286
2287                     EventLog.writeEvent(EventLogTags.CPU,
2288                             ((user+system+iowait+irq+softIrq) * 100) / total,
2289                             (user * 100) / total,
2290                             (system * 100) / total,
2291                             (iowait * 100) / total,
2292                             (irq * 100) / total,
2293                             (softIrq * 100) / total);
2294                 }
2295             }
2296
2297             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2298             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2299             synchronized(bstats) {
2300                 synchronized(mPidsSelfLocked) {
2301                     if (haveNewCpuStats) {
2302                         if (mOnBattery) {
2303                             int perc = bstats.startAddingCpuLocked();
2304                             int totalUTime = 0;
2305                             int totalSTime = 0;
2306                             final int N = mProcessCpuTracker.countStats();
2307                             for (int i=0; i<N; i++) {
2308                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2309                                 if (!st.working) {
2310                                     continue;
2311                                 }
2312                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2313                                 int otherUTime = (st.rel_utime*perc)/100;
2314                                 int otherSTime = (st.rel_stime*perc)/100;
2315                                 totalUTime += otherUTime;
2316                                 totalSTime += otherSTime;
2317                                 if (pr != null) {
2318                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2319                                     if (ps == null || !ps.isActive()) {
2320                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2321                                                 pr.info.uid, pr.processName);
2322                                     }
2323                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324                                             st.rel_stime-otherSTime);
2325                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2326                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2327                                 } else {
2328                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2329                                     if (ps == null || !ps.isActive()) {
2330                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2331                                                 bstats.mapUid(st.uid), st.name);
2332                                     }
2333                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2334                                             st.rel_stime-otherSTime);
2335                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2336                                 }
2337                             }
2338                             bstats.finishAddingCpuLocked(perc, totalUTime,
2339                                     totalSTime, cpuSpeedTimes);
2340                         }
2341                     }
2342                 }
2343
2344                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2345                     mLastWriteTime = now;
2346                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2347                 }
2348             }
2349         }
2350     }
2351
2352     @Override
2353     public void batteryNeedsCpuUpdate() {
2354         updateCpuStatsNow();
2355     }
2356
2357     @Override
2358     public void batteryPowerChanged(boolean onBattery) {
2359         // When plugging in, update the CPU stats first before changing
2360         // the plug state.
2361         updateCpuStatsNow();
2362         synchronized (this) {
2363             synchronized(mPidsSelfLocked) {
2364                 mOnBattery = DEBUG_POWER ? true : onBattery;
2365             }
2366         }
2367     }
2368
2369     /**
2370      * Initialize the application bind args. These are passed to each
2371      * process when the bindApplication() IPC is sent to the process. They're
2372      * lazily setup to make sure the services are running when they're asked for.
2373      */
2374     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2375         if (mAppBindArgs == null) {
2376             mAppBindArgs = new HashMap<>();
2377
2378             // Isolated processes won't get this optimization, so that we don't
2379             // violate the rules about which services they have access to.
2380             if (!isolated) {
2381                 // Setup the application init args
2382                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2383                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2384                 mAppBindArgs.put(Context.ALARM_SERVICE,
2385                         ServiceManager.getService(Context.ALARM_SERVICE));
2386             }
2387         }
2388         return mAppBindArgs;
2389     }
2390
2391     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2392         if (mFocusedActivity != r) {
2393             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2394             mFocusedActivity = r;
2395             if (r.task != null && r.task.voiceInteractor != null) {
2396                 startRunningVoiceLocked();
2397             } else {
2398                 finishRunningVoiceLocked();
2399             }
2400             mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2401             if (r != null) {
2402                 mWindowManager.setFocusedApp(r.appToken, true);
2403             }
2404             applyUpdateLockStateLocked(r);
2405         }
2406         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2407                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2408     }
2409
2410     final void clearFocusedActivity(ActivityRecord r) {
2411         if (mFocusedActivity == r) {
2412             mFocusedActivity = null;
2413         }
2414     }
2415
2416     @Override
2417     public void setFocusedStack(int stackId) {
2418         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2419         synchronized (ActivityManagerService.this) {
2420             ActivityStack stack = mStackSupervisor.getStack(stackId);
2421             if (stack != null) {
2422                 ActivityRecord r = stack.topRunningActivityLocked(null);
2423                 if (r != null) {
2424                     setFocusedActivityLocked(r, "setFocusedStack");
2425                 }
2426             }
2427         }
2428     }
2429
2430     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2431     @Override
2432     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2433         synchronized (ActivityManagerService.this) {
2434             if (listener != null) {
2435                 mTaskStackListeners.register(listener);
2436             }
2437         }
2438     }
2439
2440     @Override
2441     public void notifyActivityDrawn(IBinder token) {
2442         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2443         synchronized (this) {
2444             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2445             if (r != null) {
2446                 r.task.stack.notifyActivityDrawnLocked(r);
2447             }
2448         }
2449     }
2450
2451     final void applyUpdateLockStateLocked(ActivityRecord r) {
2452         // Modifications to the UpdateLock state are done on our handler, outside
2453         // the activity manager's locks.  The new state is determined based on the
2454         // state *now* of the relevant activity record.  The object is passed to
2455         // the handler solely for logging detail, not to be consulted/modified.
2456         final boolean nextState = r != null && r.immersive;
2457         mHandler.sendMessage(
2458                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2459     }
2460
2461     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2462         Message msg = Message.obtain();
2463         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2464         msg.obj = r.task.askedCompatMode ? null : r;
2465         mUiHandler.sendMessage(msg);
2466     }
2467
2468     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2469             String what, Object obj, ProcessRecord srcApp) {
2470         app.lastActivityTime = now;
2471
2472         if (app.activities.size() > 0) {
2473             // Don't want to touch dependent processes that are hosting activities.
2474             return index;
2475         }
2476
2477         int lrui = mLruProcesses.lastIndexOf(app);
2478         if (lrui < 0) {
2479             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2480                     + what + " " + obj + " from " + srcApp);
2481             return index;
2482         }
2483
2484         if (lrui >= index) {
2485             // Don't want to cause this to move dependent processes *back* in the
2486             // list as if they were less frequently used.
2487             return index;
2488         }
2489
2490         if (lrui >= mLruProcessActivityStart) {
2491             // Don't want to touch dependent processes that are hosting activities.
2492             return index;
2493         }
2494
2495         mLruProcesses.remove(lrui);
2496         if (index > 0) {
2497             index--;
2498         }
2499         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2500                 + " in LRU list: " + app);
2501         mLruProcesses.add(index, app);
2502         return index;
2503     }
2504
2505     final void removeLruProcessLocked(ProcessRecord app) {
2506         int lrui = mLruProcesses.lastIndexOf(app);
2507         if (lrui >= 0) {
2508             if (!app.killed) {
2509                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2510                 Process.killProcessQuiet(app.pid);
2511                 Process.killProcessGroup(app.info.uid, app.pid);
2512             }
2513             if (lrui <= mLruProcessActivityStart) {
2514                 mLruProcessActivityStart--;
2515             }
2516             if (lrui <= mLruProcessServiceStart) {
2517                 mLruProcessServiceStart--;
2518             }
2519             mLruProcesses.remove(lrui);
2520         }
2521     }
2522
2523     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2524             ProcessRecord client) {
2525         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2526                 || app.treatLikeActivity;
2527         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2528         if (!activityChange && hasActivity) {
2529             // The process has activities, so we are only allowing activity-based adjustments
2530             // to move it.  It should be kept in the front of the list with other
2531             // processes that have activities, and we don't want those to change their
2532             // order except due to activity operations.
2533             return;
2534         }
2535
2536         mLruSeq++;
2537         final long now = SystemClock.uptimeMillis();
2538         app.lastActivityTime = now;
2539
2540         // First a quick reject: if the app is already at the position we will
2541         // put it, then there is nothing to do.
2542         if (hasActivity) {
2543             final int N = mLruProcesses.size();
2544             if (N > 0 && mLruProcesses.get(N-1) == app) {
2545                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2546                 return;
2547             }
2548         } else {
2549             if (mLruProcessServiceStart > 0
2550                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2551                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2552                 return;
2553             }
2554         }
2555
2556         int lrui = mLruProcesses.lastIndexOf(app);
2557
2558         if (app.persistent && lrui >= 0) {
2559             // We don't care about the position of persistent processes, as long as
2560             // they are in the list.
2561             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2562             return;
2563         }
2564
2565         /* In progress: compute new position first, so we can avoid doing work
2566            if the process is not actually going to move.  Not yet working.
2567         int addIndex;
2568         int nextIndex;
2569         boolean inActivity = false, inService = false;
2570         if (hasActivity) {
2571             // Process has activities, put it at the very tipsy-top.
2572             addIndex = mLruProcesses.size();
2573             nextIndex = mLruProcessServiceStart;
2574             inActivity = true;
2575         } else if (hasService) {
2576             // Process has services, put it at the top of the service list.
2577             addIndex = mLruProcessActivityStart;
2578             nextIndex = mLruProcessServiceStart;
2579             inActivity = true;
2580             inService = true;
2581         } else  {
2582             // Process not otherwise of interest, it goes to the top of the non-service area.
2583             addIndex = mLruProcessServiceStart;
2584             if (client != null) {
2585                 int clientIndex = mLruProcesses.lastIndexOf(client);
2586                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2587                         + app);
2588                 if (clientIndex >= 0 && addIndex > clientIndex) {
2589                     addIndex = clientIndex;
2590                 }
2591             }
2592             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2593         }
2594
2595         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2596                 + mLruProcessActivityStart + "): " + app);
2597         */
2598
2599         if (lrui >= 0) {
2600             if (lrui < mLruProcessActivityStart) {
2601                 mLruProcessActivityStart--;
2602             }
2603             if (lrui < mLruProcessServiceStart) {
2604                 mLruProcessServiceStart--;
2605             }
2606             /*
2607             if (addIndex > lrui) {
2608                 addIndex--;
2609             }
2610             if (nextIndex > lrui) {
2611                 nextIndex--;
2612             }
2613             */
2614             mLruProcesses.remove(lrui);
2615         }
2616
2617         /*
2618         mLruProcesses.add(addIndex, app);
2619         if (inActivity) {
2620             mLruProcessActivityStart++;
2621         }
2622         if (inService) {
2623             mLruProcessActivityStart++;
2624         }
2625         */
2626
2627         int nextIndex;
2628         if (hasActivity) {
2629             final int N = mLruProcesses.size();
2630             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2631                 // Process doesn't have activities, but has clients with
2632                 // activities...  move it up, but one below the top (the top
2633                 // should always have a real activity).
2634                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2635                 mLruProcesses.add(N-1, app);
2636                 // To keep it from spamming the LRU list (by making a bunch of clients),
2637                 // we will push down any other entries owned by the app.
2638                 final int uid = app.info.uid;
2639                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2640                     ProcessRecord subProc = mLruProcesses.get(i);
2641                     if (subProc.info.uid == uid) {
2642                         // We want to push this one down the list.  If the process after
2643                         // it is for the same uid, however, don't do so, because we don't
2644                         // want them internally to be re-ordered.
2645                         if (mLruProcesses.get(i-1).info.uid != uid) {
2646                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2647                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2648                             ProcessRecord tmp = mLruProcesses.get(i);
2649                             mLruProcesses.set(i, mLruProcesses.get(i-1));
2650                             mLruProcesses.set(i-1, tmp);
2651                             i--;
2652                         }
2653                     } else {
2654                         // A gap, we can stop here.
2655                         break;
2656                     }
2657                 }
2658             } else {
2659                 // Process has activities, put it at the very tipsy-top.
2660                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2661                 mLruProcesses.add(app);
2662             }
2663             nextIndex = mLruProcessServiceStart;
2664         } else if (hasService) {
2665             // Process has services, put it at the top of the service list.
2666             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2667             mLruProcesses.add(mLruProcessActivityStart, app);
2668             nextIndex = mLruProcessServiceStart;
2669             mLruProcessActivityStart++;
2670         } else  {
2671             // Process not otherwise of interest, it goes to the top of the non-service area.
2672             int index = mLruProcessServiceStart;
2673             if (client != null) {
2674                 // If there is a client, don't allow the process to be moved up higher
2675                 // in the list than that client.
2676                 int clientIndex = mLruProcesses.lastIndexOf(client);
2677                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2678                         + " when updating " + app);
2679                 if (clientIndex <= lrui) {
2680                     // Don't allow the client index restriction to push it down farther in the
2681                     // list than it already is.
2682                     clientIndex = lrui;
2683                 }
2684                 if (clientIndex >= 0 && index > clientIndex) {
2685                     index = clientIndex;
2686                 }
2687             }
2688             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2689             mLruProcesses.add(index, app);
2690             nextIndex = index-1;
2691             mLruProcessActivityStart++;
2692             mLruProcessServiceStart++;
2693         }
2694
2695         // If the app is currently using a content provider or service,
2696         // bump those processes as well.
2697         for (int j=app.connections.size()-1; j>=0; j--) {
2698             ConnectionRecord cr = app.connections.valueAt(j);
2699             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2700                     && cr.binding.service.app != null
2701                     && cr.binding.service.app.lruSeq != mLruSeq
2702                     && !cr.binding.service.app.persistent) {
2703                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2704                         "service connection", cr, app);
2705             }
2706         }
2707         for (int j=app.conProviders.size()-1; j>=0; j--) {
2708             ContentProviderRecord cpr = app.conProviders.get(j).provider;
2709             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2710                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2711                         "provider reference", cpr, app);
2712             }
2713         }
2714     }
2715
2716     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2717         if (uid == Process.SYSTEM_UID) {
2718             // The system gets to run in any process.  If there are multiple
2719             // processes with the same uid, just pick the first (this
2720             // should never happen).
2721             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2722             if (procs == null) return null;
2723             final int procCount = procs.size();
2724             for (int i = 0; i < procCount; i++) {
2725                 final int procUid = procs.keyAt(i);
2726                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2727                     // Don't use an app process or different user process for system component.
2728                     continue;
2729                 }
2730                 return procs.valueAt(i);
2731             }
2732         }
2733         ProcessRecord proc = mProcessNames.get(processName, uid);
2734         if (false && proc != null && !keepIfLarge
2735                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2736                 && proc.lastCachedPss >= 4000) {
2737             // Turn this condition on to cause killing to happen regularly, for testing.
2738             if (proc.baseProcessTracker != null) {
2739                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2740             }
2741             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2742         } else if (proc != null && !keepIfLarge
2743                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2744                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2745             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2746             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2747                 if (proc.baseProcessTracker != null) {
2748                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2749                 }
2750                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2751             }
2752         }
2753         return proc;
2754     }
2755
2756     void ensurePackageDexOpt(String packageName) {
2757         IPackageManager pm = AppGlobals.getPackageManager();
2758         try {
2759             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2760                 mDidDexOpt = true;
2761             }
2762         } catch (RemoteException e) {
2763         }
2764     }
2765
2766     boolean isNextTransitionForward() {
2767         int transit = mWindowManager.getPendingAppTransition();
2768         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2769                 || transit == AppTransition.TRANSIT_TASK_OPEN
2770                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2771     }
2772
2773     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2774             String processName, String abiOverride, int uid, Runnable crashHandler) {
2775         synchronized(this) {
2776             ApplicationInfo info = new ApplicationInfo();
2777             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2778             // For isolated processes, the former contains the parent's uid and the latter the
2779             // actual uid of the isolated process.
2780             // In the special case introduced by this method (which is, starting an isolated
2781             // process directly from the SystemServer without an actual parent app process) the
2782             // closest thing to a parent's uid is SYSTEM_UID.
2783             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2784             // the |isolated| logic in the ProcessRecord constructor.
2785             info.uid = Process.SYSTEM_UID;
2786             info.processName = processName;
2787             info.className = entryPoint;
2788             info.packageName = "android";
2789             ProcessRecord proc = startProcessLocked(processName, info /* info */,
2790                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2791                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2792                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2793                     crashHandler);
2794             return proc != null ? proc.pid : 0;
2795         }
2796     }
2797
2798     final ProcessRecord startProcessLocked(String processName,
2799             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2800             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2801             boolean isolated, boolean keepIfLarge) {
2802         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2803                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2804                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2805                 null /* crashHandler */);
2806     }
2807
2808     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2809             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2810             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2811             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2812         long startTime = SystemClock.elapsedRealtime();
2813         ProcessRecord app;
2814         if (!isolated) {
2815             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2816             checkTime(startTime, "startProcess: after getProcessRecord");
2817
2818             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2819                 // If we are in the background, then check to see if this process
2820                 // is bad.  If so, we will just silently fail.
2821                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2822                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823                             + "/" + info.processName);
2824                     return null;
2825                 }
2826             } else {
2827                 // When the user is explicitly starting a process, then clear its
2828                 // crash count so that we won't make it bad until they see at
2829                 // least one crash dialog again, and make the process good again
2830                 // if it had been bad.
2831                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832                         + "/" + info.processName);
2833                 mProcessCrashTimes.remove(info.processName, info.uid);
2834                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2835                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836                             UserHandle.getUserId(info.uid), info.uid,
2837                             info.processName);
2838                     mBadProcesses.remove(info.processName, info.uid);
2839                     if (app != null) {
2840                         app.bad = false;
2841                     }
2842                 }
2843             }
2844         } else {
2845             // If this is an isolated process, it can't re-use an existing process.
2846             app = null;
2847         }
2848
2849         // We don't have to do anything more if:
2850         // (1) There is an existing application record; and
2851         // (2) The caller doesn't think it is dead, OR there is no thread
2852         //     object attached to it so we know it couldn't have crashed; and
2853         // (3) There is a pid assigned to it, so it is either starting or
2854         //     already running.
2855         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2856                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2857                 + " thread=" + (app != null ? app.thread : null)
2858                 + " pid=" + (app != null ? app.pid : -1));
2859         if (app != null && app.pid > 0) {
2860             if (!knownToBeDead || app.thread == null) {
2861                 // We already have the app running, or are waiting for it to
2862                 // come up (we have a pid but not yet its thread), so keep it.
2863                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2864                 // If this is a new package in the process, add the package to the list
2865                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2866                 checkTime(startTime, "startProcess: done, added package to proc");
2867                 return app;
2868             }
2869
2870             // An application record is attached to a previous process,
2871             // clean it up now.
2872             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2873             checkTime(startTime, "startProcess: bad proc running, killing");
2874             Process.killProcessGroup(app.info.uid, app.pid);
2875             handleAppDiedLocked(app, true, true);
2876             checkTime(startTime, "startProcess: done killing old proc");
2877         }
2878
2879         String hostingNameStr = hostingName != null
2880                 ? hostingName.flattenToShortString() : null;
2881
2882         if (app == null) {
2883             checkTime(startTime, "startProcess: creating new process record");
2884             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2885             if (app == null) {
2886                 Slog.w(TAG, "Failed making new process record for "
2887                         + processName + "/" + info.uid + " isolated=" + isolated);
2888                 return null;
2889             }
2890             app.crashHandler = crashHandler;
2891             mProcessNames.put(processName, app.uid, app);
2892             if (isolated) {
2893                 mIsolatedProcesses.put(app.uid, app);
2894             }
2895             checkTime(startTime, "startProcess: done creating new process record");
2896         } else {
2897             // If this is a new package in the process, add the package to the list
2898             app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899             checkTime(startTime, "startProcess: added package to existing proc");
2900         }
2901
2902         // If the system is not ready yet, then hold off on starting this
2903         // process until it is.
2904         if (!mProcessesReady
2905                 && !isAllowedWhileBooting(info)
2906                 && !allowWhileBooting) {
2907             if (!mProcessesOnHold.contains(app)) {
2908                 mProcessesOnHold.add(app);
2909             }
2910             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2911             checkTime(startTime, "startProcess: returning with proc on hold");
2912             return app;
2913         }
2914
2915         checkTime(startTime, "startProcess: stepping in to startProcess");
2916         startProcessLocked(
2917                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2918         checkTime(startTime, "startProcess: done starting proc!");
2919         return (app.pid != 0) ? app : null;
2920     }
2921
2922     boolean isAllowedWhileBooting(ApplicationInfo ai) {
2923         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2924     }
2925
2926     private final void startProcessLocked(ProcessRecord app,
2927             String hostingType, String hostingNameStr) {
2928         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2929                 null /* entryPoint */, null /* entryPointArgs */);
2930     }
2931
2932     private final void startProcessLocked(ProcessRecord app, String hostingType,
2933             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2934         long startTime = SystemClock.elapsedRealtime();
2935         if (app.pid > 0 && app.pid != MY_PID) {
2936             checkTime(startTime, "startProcess: removing from pids map");
2937             synchronized (mPidsSelfLocked) {
2938                 mPidsSelfLocked.remove(app.pid);
2939                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2940             }
2941             checkTime(startTime, "startProcess: done removing from pids map");
2942             app.setPid(0);
2943         }
2944
2945         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2946                 "startProcessLocked removing on hold: " + app);
2947         mProcessesOnHold.remove(app);
2948
2949         checkTime(startTime, "startProcess: starting to update cpu stats");
2950         updateCpuStats();
2951         checkTime(startTime, "startProcess: done updating cpu stats");
2952
2953         try {
2954             int uid = app.uid;
2955
2956             int[] gids = null;
2957             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2958             if (!app.isolated) {
2959                 int[] permGids = null;
2960                 try {
2961                     checkTime(startTime, "startProcess: getting gids from package manager");
2962                     final PackageManager pm = mContext.getPackageManager();
2963                     permGids = pm.getPackageGids(app.info.packageName);
2964
2965                     if (Environment.isExternalStorageEmulated()) {
2966                         checkTime(startTime, "startProcess: checking external storage perm");
2967                         if (pm.checkPermission(
2968                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969                                 app.info.packageName) == PERMISSION_GRANTED) {
2970                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2971                         } else {
2972                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2973                         }
2974                     }
2975                 } catch (PackageManager.NameNotFoundException e) {
2976                     Slog.w(TAG, "Unable to retrieve gids", e);
2977                 }
2978
2979                 /*
2980                  * Add shared application and profile GIDs so applications can share some
2981                  * resources like shared libraries and access user-wide resources
2982                  */
2983                 if (permGids == null) {
2984                     gids = new int[2];
2985                 } else {
2986                     gids = new int[permGids.length + 2];
2987                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
2988                 }
2989                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2991             }
2992             checkTime(startTime, "startProcess: building args");
2993             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2994                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2995                         && mTopComponent != null
2996                         && app.processName.equals(mTopComponent.getPackageName())) {
2997                     uid = 0;
2998                 }
2999                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3000                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3001                     uid = 0;
3002                 }
3003             }
3004             int debugFlags = 0;
3005             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3006                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3007                 // Also turn on CheckJNI for debuggable apps. It's quite
3008                 // awkward to turn on otherwise.
3009                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3010             }
3011             // Run the app in safe mode if its manifest requests so or the
3012             // system is booted in safe mode.
3013             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3014                 mSafeMode == true) {
3015                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3016             }
3017             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3018                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3019             }
3020             String jitDebugProperty = SystemProperties.get("debug.usejit");
3021             if ("true".equals(jitDebugProperty)) {
3022                 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3023             } else if (!"false".equals(jitDebugProperty)) {
3024                 // If we didn't force disable by setting false, defer to the dalvik vm options.
3025                 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3026                     debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3027                 }
3028             }
3029             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3030                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3031             }
3032             if ("1".equals(SystemProperties.get("debug.assert"))) {
3033                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3034             }
3035
3036             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3037             if (requiredAbi == null) {
3038                 requiredAbi = Build.SUPPORTED_ABIS[0];
3039             }
3040
3041             String instructionSet = null;
3042             if (app.info.primaryCpuAbi != null) {
3043                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3044             }
3045
3046             app.gids = gids;
3047             app.requiredAbi = requiredAbi;
3048             app.instructionSet = instructionSet;
3049
3050             // Start the process.  It will either succeed and return a result containing
3051             // the PID of the new process, or else throw a RuntimeException.
3052             boolean isActivityProcess = (entryPoint == null);
3053             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3054             checkTime(startTime, "startProcess: asking zygote to start proc");
3055             Process.ProcessStartResult startResult = Process.start(entryPoint,
3056                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3057                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3058                     app.info.dataDir, entryPointArgs);
3059             checkTime(startTime, "startProcess: returned from zygote!");
3060
3061             if (app.isolated) {
3062                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3063             }
3064             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3065             checkTime(startTime, "startProcess: done updating battery stats");
3066
3067             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3068                     UserHandle.getUserId(uid), startResult.pid, uid,
3069                     app.processName, hostingType,
3070                     hostingNameStr != null ? hostingNameStr : "");
3071
3072             if (app.persistent) {
3073                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3074             }
3075
3076             checkTime(startTime, "startProcess: building log message");
3077             StringBuilder buf = mStringBuilder;
3078             buf.setLength(0);
3079             buf.append("Start proc ");
3080             buf.append(startResult.pid);
3081             buf.append(':');
3082             buf.append(app.processName);
3083             buf.append('/');
3084             UserHandle.formatUid(buf, uid);
3085             if (!isActivityProcess) {
3086                 buf.append(" [");
3087                 buf.append(entryPoint);
3088                 buf.append("]");
3089             }
3090             buf.append(" for ");
3091             buf.append(hostingType);
3092             if (hostingNameStr != null) {
3093                 buf.append(" ");
3094                 buf.append(hostingNameStr);
3095             }
3096             Slog.i(TAG, buf.toString());
3097             app.setPid(startResult.pid);
3098             app.usingWrapper = startResult.usingWrapper;
3099             app.removed = false;
3100             app.killed = false;
3101             app.killedByAm = false;
3102             checkTime(startTime, "startProcess: starting to update pids map");
3103             synchronized (mPidsSelfLocked) {
3104                 this.mPidsSelfLocked.put(startResult.pid, app);
3105                 if (isActivityProcess) {
3106                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3107                     msg.obj = app;
3108                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3109                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3110                 }
3111             }
3112             checkTime(startTime, "startProcess: done updating pids map");
3113         } catch (RuntimeException e) {
3114             // XXX do better error recovery.
3115             app.setPid(0);
3116             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3117             if (app.isolated) {
3118                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3119             }
3120             Slog.e(TAG, "Failure starting process " + app.processName, e);
3121         }
3122     }
3123
3124     void updateUsageStats(ActivityRecord component, boolean resumed) {
3125         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3126         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3127         if (resumed) {
3128             if (mUsageStatsService != null) {
3129                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3130                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3131             }
3132             synchronized (stats) {
3133                 stats.noteActivityResumedLocked(component.app.uid);
3134             }
3135         } else {
3136             if (mUsageStatsService != null) {
3137                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3138                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3139             }
3140             synchronized (stats) {
3141                 stats.noteActivityPausedLocked(component.app.uid);
3142             }
3143         }
3144     }
3145
3146     Intent getHomeIntent() {
3147         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3148         intent.setComponent(mTopComponent);
3149         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3150             intent.addCategory(Intent.CATEGORY_HOME);
3151         }
3152         return intent;
3153     }
3154
3155     boolean startHomeActivityLocked(int userId, String reason) {
3156         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3157                 && mTopAction == null) {
3158             // We are running in factory test mode, but unable to find
3159             // the factory test app, so just sit around displaying the
3160             // error message and don't try to start anything.
3161             return false;
3162         }
3163         Intent intent = getHomeIntent();
3164         ActivityInfo aInfo =
3165             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3166         if (aInfo != null) {
3167             intent.setComponent(new ComponentName(
3168                     aInfo.applicationInfo.packageName, aInfo.name));
3169             // Don't do this if the home app is currently being
3170             // instrumented.
3171             aInfo = new ActivityInfo(aInfo);
3172             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3173             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3174                     aInfo.applicationInfo.uid, true);
3175             if (app == null || app.instrumentationClass == null) {
3176                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3177                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3178             }
3179         }
3180
3181         return true;
3182     }
3183
3184     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3185         ActivityInfo ai = null;
3186         ComponentName comp = intent.getComponent();
3187         try {
3188             if (comp != null) {
3189                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3190             } else {
3191                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3192                         intent,
3193                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3194                             flags, userId);
3195
3196                 if (info != null) {
3197                     ai = info.activityInfo;
3198                 }
3199             }
3200         } catch (RemoteException e) {
3201             // ignore
3202         }
3203
3204         return ai;
3205     }
3206
3207     /**
3208      * Starts the "new version setup screen" if appropriate.
3209      */
3210     void startSetupActivityLocked() {
3211         // Only do this once per boot.
3212         if (mCheckedForSetup) {
3213             return;
3214         }
3215
3216         // We will show this screen if the current one is a different
3217         // version than the last one shown, and we are not running in
3218         // low-level factory test mode.
3219         final ContentResolver resolver = mContext.getContentResolver();
3220         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3221                 Settings.Global.getInt(resolver,
3222                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3223             mCheckedForSetup = true;
3224
3225             // See if we should be showing the platform update setup UI.
3226             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3227             List<ResolveInfo> ris = mContext.getPackageManager()
3228                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3229
3230             // We don't allow third party apps to replace this.
3231             ResolveInfo ri = null;
3232             for (int i=0; ris != null && i<ris.size(); i++) {
3233                 if ((ris.get(i).activityInfo.applicationInfo.flags
3234                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3235                     ri = ris.get(i);
3236                     break;
3237                 }
3238             }
3239
3240             if (ri != null) {
3241                 String vers = ri.activityInfo.metaData != null
3242                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3243                         : null;
3244                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3245                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3246                             Intent.METADATA_SETUP_VERSION);
3247                 }
3248                 String lastVers = Settings.Secure.getString(
3249                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3250                 if (vers != null && !vers.equals(lastVers)) {
3251                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3252                     intent.setComponent(new ComponentName(
3253                             ri.activityInfo.packageName, ri.activityInfo.name));
3254                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3255                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3256                             null);
3257                 }
3258             }
3259         }
3260     }
3261
3262     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3263         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3264     }
3265
3266     void enforceNotIsolatedCaller(String caller) {
3267         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3268             throw new SecurityException("Isolated process not allowed to call " + caller);
3269         }
3270     }
3271
3272     void enforceShellRestriction(String restriction, int userHandle) {
3273         if (Binder.getCallingUid() == Process.SHELL_UID) {
3274             if (userHandle < 0
3275                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3276                 throw new SecurityException("Shell does not have permission to access user "
3277                         + userHandle);
3278             }
3279         }
3280     }
3281
3282     @Override
3283     public int getFrontActivityScreenCompatMode() {
3284         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3285         synchronized (this) {
3286             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3287         }
3288     }
3289
3290     @Override
3291     public void setFrontActivityScreenCompatMode(int mode) {
3292         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3293                 "setFrontActivityScreenCompatMode");
3294         synchronized (this) {
3295             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3296         }
3297     }
3298
3299     @Override
3300     public int getPackageScreenCompatMode(String packageName) {
3301         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3302         synchronized (this) {
3303             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3304         }
3305     }
3306
3307     @Override
3308     public void setPackageScreenCompatMode(String packageName, int mode) {
3309         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3310                 "setPackageScreenCompatMode");
3311         synchronized (this) {
3312             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3313         }
3314     }
3315
3316     @Override
3317     public boolean getPackageAskScreenCompat(String packageName) {
3318         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3319         synchronized (this) {
3320             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3321         }
3322     }
3323
3324     @Override
3325     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3326         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3327                 "setPackageAskScreenCompat");
3328         synchronized (this) {
3329             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3330         }
3331     }
3332
3333     private void dispatchProcessesChanged() {
3334         int N;
3335         synchronized (this) {
3336             N = mPendingProcessChanges.size();
3337             if (mActiveProcessChanges.length < N) {
3338                 mActiveProcessChanges = new ProcessChangeItem[N];
3339             }
3340             mPendingProcessChanges.toArray(mActiveProcessChanges);
3341             mAvailProcessChanges.addAll(mPendingProcessChanges);
3342             mPendingProcessChanges.clear();
3343             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3344         }
3345
3346         int i = mProcessObservers.beginBroadcast();
3347         while (i > 0) {
3348             i--;
3349             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3350             if (observer != null) {
3351                 try {
3352                     for (int j=0; j<N; j++) {
3353                         ProcessChangeItem item = mActiveProcessChanges[j];
3354                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3355                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3356                                     + item.pid + " uid=" + item.uid + ": "
3357                                     + item.foregroundActivities);
3358                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3359                                     item.foregroundActivities);
3360                         }
3361                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3362                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3363                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
3364                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3365                         }
3366                     }
3367                 } catch (RemoteException e) {
3368                 }
3369             }
3370         }
3371         mProcessObservers.finishBroadcast();
3372     }
3373
3374     private void dispatchProcessDied(int pid, int uid) {
3375         int i = mProcessObservers.beginBroadcast();
3376         while (i > 0) {
3377             i--;
3378             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3379             if (observer != null) {
3380                 try {
3381                     observer.onProcessDied(pid, uid);
3382                 } catch (RemoteException e) {
3383                 }
3384             }
3385         }
3386         mProcessObservers.finishBroadcast();
3387     }
3388
3389     @Override
3390     public final int startActivity(IApplicationThread caller, String callingPackage,
3391             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3392             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3393         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3394             resultWho, requestCode, startFlags, profilerInfo, options,
3395             UserHandle.getCallingUserId());
3396     }
3397
3398     @Override
3399     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3400             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3401             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3402         enforceNotIsolatedCaller("startActivity");
3403         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404                 false, ALLOW_FULL_ONLY, "startActivity", null);
3405         // TODO: Switch to user app stacks here.
3406         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408                 profilerInfo, null, null, options, userId, null, null);
3409     }
3410
3411     @Override
3412     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3413             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3414             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3415
3416         // This is very dangerous -- it allows you to perform a start activity (including
3417         // permission grants) as any app that may launch one of your own activities.  So
3418         // we will only allow this to be done from activities that are part of the core framework,
3419         // and then only when they are running as the system.
3420         final ActivityRecord sourceRecord;
3421         final int targetUid;
3422         final String targetPackage;
3423         synchronized (this) {
3424             if (resultTo == null) {
3425                 throw new SecurityException("Must be called from an activity");
3426             }
3427             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3428             if (sourceRecord == null) {
3429                 throw new SecurityException("Called with bad activity token: " + resultTo);
3430             }
3431             if (!sourceRecord.info.packageName.equals("android")) {
3432                 throw new SecurityException(
3433                         "Must be called from an activity that is declared in the android package");
3434             }
3435             if (sourceRecord.app == null) {
3436                 throw new SecurityException("Called without a process attached to activity");
3437             }
3438             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3439                 // This is still okay, as long as this activity is running under the
3440                 // uid of the original calling activity.
3441                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3442                     throw new SecurityException(
3443                             "Calling activity in uid " + sourceRecord.app.uid
3444                                     + " must be system uid or original calling uid "
3445                                     + sourceRecord.launchedFromUid);
3446                 }
3447             }
3448             targetUid = sourceRecord.launchedFromUid;
3449             targetPackage = sourceRecord.launchedFromPackage;
3450         }
3451
3452         if (userId == UserHandle.USER_NULL) {
3453             userId = UserHandle.getUserId(sourceRecord.app.uid);
3454         }
3455
3456         // TODO: Switch to user app stacks here.
3457         try {
3458             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3459                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3460                     null, null, options, userId, null, null);
3461             return ret;
3462         } catch (SecurityException e) {
3463             // XXX need to figure out how to propagate to original app.
3464             // A SecurityException here is generally actually a fault of the original
3465             // calling activity (such as a fairly granting permissions), so propagate it
3466             // back to them.
3467             /*
3468             StringBuilder msg = new StringBuilder();
3469             msg.append("While launching");
3470             msg.append(intent.toString());
3471             msg.append(": ");
3472             msg.append(e.getMessage());
3473             */
3474             throw e;
3475         }
3476     }
3477
3478     @Override
3479     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3480             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3481             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3482         enforceNotIsolatedCaller("startActivityAndWait");
3483         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3484                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3485         WaitResult res = new WaitResult();
3486         // TODO: Switch to user app stacks here.
3487         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3488                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3489                 options, userId, null, null);
3490         return res;
3491     }
3492
3493     @Override
3494     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3495             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3496             int startFlags, Configuration config, Bundle options, int userId) {
3497         enforceNotIsolatedCaller("startActivityWithConfig");
3498         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3499                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3500         // TODO: Switch to user app stacks here.
3501         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3502                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3503                 null, null, config, options, userId, null, null);
3504         return ret;
3505     }
3506
3507     @Override
3508     public int startActivityIntentSender(IApplicationThread caller,
3509             IntentSender intent, Intent fillInIntent, String resolvedType,
3510             IBinder resultTo, String resultWho, int requestCode,
3511             int flagsMask, int flagsValues, Bundle options) {
3512         enforceNotIsolatedCaller("startActivityIntentSender");
3513         // Refuse possible leaked file descriptors
3514         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3515             throw new IllegalArgumentException("File descriptors passed in Intent");
3516         }
3517
3518         IIntentSender sender = intent.getTarget();
3519         if (!(sender instanceof PendingIntentRecord)) {
3520             throw new IllegalArgumentException("Bad PendingIntent object");
3521         }
3522
3523         PendingIntentRecord pir = (PendingIntentRecord)sender;
3524
3525         synchronized (this) {
3526             // If this is coming from the currently resumed activity, it is
3527             // effectively saying that app switches are allowed at this point.
3528             final ActivityStack stack = getFocusedStack();
3529             if (stack.mResumedActivity != null &&
3530                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3531                 mAppSwitchesAllowedTime = 0;
3532             }
3533         }
3534         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3535                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3536         return ret;
3537     }
3538
3539     @Override
3540     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3541             Intent intent, String resolvedType, IVoiceInteractionSession session,
3542             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3543             Bundle options, int userId) {
3544         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3545                 != PackageManager.PERMISSION_GRANTED) {
3546             String msg = "Permission Denial: startVoiceActivity() from pid="
3547                     + Binder.getCallingPid()
3548                     + ", uid=" + Binder.getCallingUid()
3549                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3550             Slog.w(TAG, msg);
3551             throw new SecurityException(msg);
3552         }
3553         if (session == null || interactor == null) {
3554             throw new NullPointerException("null session or interactor");
3555         }
3556         userId = handleIncomingUser(callingPid, callingUid, userId,
3557                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3558         // TODO: Switch to user app stacks here.
3559         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3560                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3561                 null, options, userId, null, null);
3562     }
3563
3564     @Override
3565     public boolean startNextMatchingActivity(IBinder callingActivity,
3566             Intent intent, Bundle options) {
3567         // Refuse possible leaked file descriptors
3568         if (intent != null && intent.hasFileDescriptors() == true) {
3569             throw new IllegalArgumentException("File descriptors passed in Intent");
3570         }
3571
3572         synchronized (this) {
3573             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3574             if (r == null) {
3575                 ActivityOptions.abort(options);
3576                 return false;
3577             }
3578             if (r.app == null || r.app.thread == null) {
3579                 // The caller is not running...  d'oh!
3580                 ActivityOptions.abort(options);
3581                 return false;
3582             }
3583             intent = new Intent(intent);
3584             // The caller is not allowed to change the data.
3585             intent.setDataAndType(r.intent.getData(), r.intent.getType());
3586             // And we are resetting to find the next component...
3587             intent.setComponent(null);
3588
3589             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3590
3591             ActivityInfo aInfo = null;
3592             try {
3593                 List<ResolveInfo> resolves =
3594                     AppGlobals.getPackageManager().queryIntentActivities(
3595                             intent, r.resolvedType,
3596                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3597                             UserHandle.getCallingUserId());
3598
3599                 // Look for the original activity in the list...
3600                 final int N = resolves != null ? resolves.size() : 0;
3601                 for (int i=0; i<N; i++) {
3602                     ResolveInfo rInfo = resolves.get(i);
3603                     if (rInfo.activityInfo.packageName.equals(r.packageName)
3604                             && rInfo.activityInfo.name.equals(r.info.name)) {
3605                         // We found the current one...  the next matching is
3606                         // after it.
3607                         i++;
3608                         if (i<N) {
3609                             aInfo = resolves.get(i).activityInfo;
3610                         }
3611                         if (debug) {
3612                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
3613                                     + "/" + r.info.name);
3614                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3615                                     + "/" + aInfo.name);
3616                         }
3617                         break;
3618                     }
3619                 }
3620             } catch (RemoteException e) {
3621             }
3622
3623             if (aInfo == null) {
3624                 // Nobody who is next!
3625                 ActivityOptions.abort(options);
3626                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3627                 return false;
3628             }
3629
3630             intent.setComponent(new ComponentName(
3631                     aInfo.applicationInfo.packageName, aInfo.name));
3632             intent.setFlags(intent.getFlags()&~(
3633                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3634                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
3635                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3636                     Intent.FLAG_ACTIVITY_NEW_TASK));
3637
3638             // Okay now we need to start the new activity, replacing the
3639             // currently running activity.  This is a little tricky because
3640             // we want to start the new one as if the current one is finished,
3641             // but not finish the current one first so that there is no flicker.
3642             // And thus...
3643             final boolean wasFinishing = r.finishing;
3644             r.finishing = true;
3645
3646             // Propagate reply information over to the new activity.
3647             final ActivityRecord resultTo = r.resultTo;
3648             final String resultWho = r.resultWho;
3649             final int requestCode = r.requestCode;
3650             r.resultTo = null;
3651             if (resultTo != null) {
3652                 resultTo.removeResultsLocked(r, resultWho, requestCode);
3653             }
3654
3655             final long origId = Binder.clearCallingIdentity();
3656             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3657                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3658                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3659                     -1, r.launchedFromUid, 0, options, false, null, null, null);
3660             Binder.restoreCallingIdentity(origId);
3661
3662             r.finishing = wasFinishing;
3663             if (res != ActivityManager.START_SUCCESS) {
3664                 return false;
3665             }
3666             return true;
3667         }
3668     }
3669
3670     @Override
3671     public final int startActivityFromRecents(int taskId, Bundle options) {
3672         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3673             String msg = "Permission Denial: startActivityFromRecents called without " +
3674                     START_TASKS_FROM_RECENTS;
3675             Slog.w(TAG, msg);
3676             throw new SecurityException(msg);
3677         }
3678         return startActivityFromRecentsInner(taskId, options);
3679     }
3680
3681     final int startActivityFromRecentsInner(int taskId, Bundle options) {
3682         final TaskRecord task;
3683         final int callingUid;
3684         final String callingPackage;
3685         final Intent intent;
3686         final int userId;
3687         synchronized (this) {
3688             task = recentTaskForIdLocked(taskId);
3689             if (task == null) {
3690                 throw new IllegalArgumentException("Task " + taskId + " not found.");
3691             }
3692             if (task.getRootActivity() != null) {
3693                 moveTaskToFrontLocked(task.taskId, 0, null);
3694                 return ActivityManager.START_TASK_TO_FRONT;
3695             }
3696             callingUid = task.mCallingUid;
3697             callingPackage = task.mCallingPackage;
3698             intent = task.intent;
3699             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3700             userId = task.userId;
3701         }
3702         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3703                 options, userId, null, task);
3704     }
3705
3706     final int startActivityInPackage(int uid, String callingPackage,
3707             Intent intent, String resolvedType, IBinder resultTo,
3708             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3709             IActivityContainer container, TaskRecord inTask) {
3710
3711         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3712                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3713
3714         // TODO: Switch to user app stacks here.
3715         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3716                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3717                 null, null, null, options, userId, container, inTask);
3718         return ret;
3719     }
3720
3721     @Override
3722     public final int startActivities(IApplicationThread caller, String callingPackage,
3723             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3724             int userId) {
3725         enforceNotIsolatedCaller("startActivities");
3726         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3727                 false, ALLOW_FULL_ONLY, "startActivity", null);
3728         // TODO: Switch to user app stacks here.
3729         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3730                 resolvedTypes, resultTo, options, userId);
3731         return ret;
3732     }
3733
3734     final int startActivitiesInPackage(int uid, String callingPackage,
3735             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3736             Bundle options, int userId) {
3737
3738         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3739                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3740         // TODO: Switch to user app stacks here.
3741         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3742                 resultTo, options, userId);
3743         return ret;
3744     }
3745
3746     //explicitly remove thd old information in mRecentTasks when removing existing user.
3747     private void removeRecentTasksForUserLocked(int userId) {
3748         if(userId <= 0) {
3749             Slog.i(TAG, "Can't remove recent task on user " + userId);
3750             return;
3751         }
3752
3753         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3754             TaskRecord tr = mRecentTasks.get(i);
3755             if (tr.userId == userId) {
3756                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3757                         + " when finishing user" + userId);
3758                 mRecentTasks.remove(i);
3759                 tr.removedFromRecents();
3760             }
3761         }
3762
3763         // Remove tasks from persistent storage.
3764         notifyTaskPersisterLocked(null, true);
3765     }
3766
3767     // Sort by taskId
3768     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3769         @Override
3770         public int compare(TaskRecord lhs, TaskRecord rhs) {
3771             return rhs.taskId - lhs.taskId;
3772         }
3773     };
3774
3775     // Extract the affiliates of the chain containing mRecentTasks[start].
3776     private int processNextAffiliateChainLocked(int start) {
3777         final TaskRecord startTask = mRecentTasks.get(start);
3778         final int affiliateId = startTask.mAffiliatedTaskId;
3779
3780         // Quick identification of isolated tasks. I.e. those not launched behind.
3781         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3782                 startTask.mNextAffiliate == null) {
3783             // There is still a slim chance that there are other tasks that point to this task
3784             // and that the chain is so messed up that this task no longer points to them but
3785             // the gain of this optimization outweighs the risk.
3786             startTask.inRecents = true;
3787             return start + 1;
3788         }
3789
3790         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3791         mTmpRecents.clear();
3792         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3793             final TaskRecord task = mRecentTasks.get(i);
3794             if (task.mAffiliatedTaskId == affiliateId) {
3795                 mRecentTasks.remove(i);
3796                 mTmpRecents.add(task);
3797             }
3798         }
3799
3800         // Sort them all by taskId. That is the order they were create in and that order will
3801         // always be correct.
3802         Collections.sort(mTmpRecents, mTaskRecordComparator);
3803
3804         // Go through and fix up the linked list.
3805         // The first one is the end of the chain and has no next.
3806         final TaskRecord first = mTmpRecents.get(0);
3807         first.inRecents = true;
3808         if (first.mNextAffiliate != null) {
3809             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3810             first.setNextAffiliate(null);
3811             notifyTaskPersisterLocked(first, false);
3812         }
3813         // Everything in the middle is doubly linked from next to prev.
3814         final int tmpSize = mTmpRecents.size();
3815         for (int i = 0; i < tmpSize - 1; ++i) {
3816             final TaskRecord next = mTmpRecents.get(i);
3817             final TaskRecord prev = mTmpRecents.get(i + 1);
3818             if (next.mPrevAffiliate != prev) {
3819                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3820                         " setting prev=" + prev);
3821                 next.setPrevAffiliate(prev);
3822                 notifyTaskPersisterLocked(next, false);
3823             }
3824             if (prev.mNextAffiliate != next) {
3825                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3826                         " setting next=" + next);
3827                 prev.setNextAffiliate(next);
3828                 notifyTaskPersisterLocked(prev, false);
3829             }
3830             prev.inRecents = true;
3831         }
3832         // The last one is the beginning of the list and has no prev.
3833         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3834         if (last.mPrevAffiliate != null) {
3835             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3836             last.setPrevAffiliate(null);
3837             notifyTaskPersisterLocked(last, false);
3838         }
3839
3840         // Insert the group back into mRecentTasks at start.
3841         mRecentTasks.addAll(start, mTmpRecents);
3842
3843         // Let the caller know where we left off.
3844         return start + tmpSize;
3845     }
3846
3847     /**
3848      * Update the recent tasks lists: make sure tasks should still be here (their
3849      * applications / activities still exist), update their availability, fixup ordering
3850      * of affiliations.
3851      */
3852     void cleanupRecentTasksLocked(int userId) {
3853         if (mRecentTasks == null) {
3854             // Happens when called from the packagemanager broadcast before boot.
3855             return;
3856         }
3857
3858         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3859         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3860         final IPackageManager pm = AppGlobals.getPackageManager();
3861         final ActivityInfo dummyAct = new ActivityInfo();
3862         final ApplicationInfo dummyApp = new ApplicationInfo();
3863
3864         int N = mRecentTasks.size();
3865
3866         int[] users = userId == UserHandle.USER_ALL
3867                 ? getUsersLocked() : new int[] { userId };
3868         for (int user : users) {
3869             for (int i = 0; i < N; i++) {
3870                 TaskRecord task = mRecentTasks.get(i);
3871                 if (task.userId != user) {
3872                     // Only look at tasks for the user ID of interest.
3873                     continue;
3874                 }
3875                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
3876                     // This situation is broken, and we should just get rid of it now.
3877                     mRecentTasks.remove(i);
3878                     task.removedFromRecents();
3879                     i--;
3880                     N--;
3881                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
3882                     continue;
3883                 }
3884                 // Check whether this activity is currently available.
3885                 if (task.realActivity != null) {
3886                     ActivityInfo ai = availActCache.get(task.realActivity);
3887                     if (ai == null) {
3888                         try {
3889                             ai = pm.getActivityInfo(task.realActivity,
3890                                     PackageManager.GET_UNINSTALLED_PACKAGES
3891                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
3892                         } catch (RemoteException e) {
3893                             // Will never happen.
3894                             continue;
3895                         }
3896                         if (ai == null) {
3897                             ai = dummyAct;
3898                         }
3899                         availActCache.put(task.realActivity, ai);
3900                     }
3901                     if (ai == dummyAct) {
3902                         // This could be either because the activity no longer exists, or the
3903                         // app is temporarily gone.  For the former we want to remove the recents
3904                         // entry; for the latter we want to mark it as unavailable.
3905                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3906                         if (app == null) {
3907                             try {
3908                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3909                                         PackageManager.GET_UNINSTALLED_PACKAGES
3910                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
3911                             } catch (RemoteException e) {
3912                                 // Will never happen.
3913                                 continue;
3914                             }
3915                             if (app == null) {
3916                                 app = dummyApp;
3917                             }
3918                             availAppCache.put(task.realActivity.getPackageName(), app);
3919                         }
3920                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3921                             // Doesn't exist any more!  Good-bye.
3922                             mRecentTasks.remove(i);
3923                             task.removedFromRecents();
3924                             i--;
3925                             N--;
3926                             Slog.w(TAG, "Removing no longer valid recent: " + task);
3927                             continue;
3928                         } else {
3929                             // Otherwise just not available for now.
3930                             if (task.isAvailable) {
3931                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3932                                         + task);
3933                             }
3934                             task.isAvailable = false;
3935                         }
3936                     } else {
3937                         if (!ai.enabled || !ai.applicationInfo.enabled
3938                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3939                             if (task.isAvailable) {
3940                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3941                                         + task + " (enabled=" + ai.enabled + "/"
3942                                         + ai.applicationInfo.enabled +  " flags="
3943                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
3944                             }
3945                             task.isAvailable = false;
3946                         } else {
3947                             if (!task.isAvailable) {
3948                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3949                                         + task);
3950                             }
3951                             task.isAvailable = true;
3952                         }
3953                     }
3954                 }
3955             }
3956         }
3957
3958         // Verify the affiliate chain for each task.
3959         for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3960         }
3961
3962         mTmpRecents.clear();
3963         // mRecentTasks is now in sorted, affiliated order.
3964     }
3965
3966     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3967         int N = mRecentTasks.size();
3968         TaskRecord top = task;
3969         int topIndex = taskIndex;
3970         while (top.mNextAffiliate != null && topIndex > 0) {
3971             top = top.mNextAffiliate;
3972             topIndex--;
3973         }
3974         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3975                 + topIndex + " from intial " + taskIndex);
3976         // Find the end of the chain, doing a sanity check along the way.
3977         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3978         int endIndex = topIndex;
3979         TaskRecord prev = top;
3980         while (endIndex < N) {
3981             TaskRecord cur = mRecentTasks.get(endIndex);
3982             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3983                     + endIndex + " " + cur);
3984             if (cur == top) {
3985                 // Verify start of the chain.
3986                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3987                     Slog.wtf(TAG, "Bad chain @" + endIndex
3988                             + ": first task has next affiliate: " + prev);
3989                     sane = false;
3990                     break;
3991                 }
3992             } else {
3993                 // Verify middle of the chain's next points back to the one before.
3994                 if (cur.mNextAffiliate != prev
3995                         || cur.mNextAffiliateTaskId != prev.taskId) {
3996                     Slog.wtf(TAG, "Bad chain @" + endIndex
3997                             + ": middle task " + cur + " @" + endIndex
3998                             + " has bad next affiliate "
3999                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4000                             + ", expected " + prev);
4001                     sane = false;
4002                     break;
4003                 }
4004             }
4005             if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
4006                 // Chain ends here.
4007                 if (cur.mPrevAffiliate != null) {
4008                     Slog.wtf(TAG, "Bad chain @" + endIndex
4009                             + ": last task " + cur + " has previous affiliate "
4010                             + cur.mPrevAffiliate);
4011                     sane = false;
4012                 }
4013                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4014                 break;
4015             } else {
4016                 // Verify middle of the chain's prev points to a valid item.
4017                 if (cur.mPrevAffiliate == null) {
4018                     Slog.wtf(TAG, "Bad chain @" + endIndex
4019                             + ": task " + cur + " has previous affiliate "
4020                             + cur.mPrevAffiliate + " but should be id "
4021                             + cur.mPrevAffiliate);
4022                     sane = false;
4023                     break;
4024                 }
4025             }
4026             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4027                 Slog.wtf(TAG, "Bad chain @" + endIndex
4028                         + ": task " + cur + " has affiliated id "
4029                         + cur.mAffiliatedTaskId + " but should be "
4030                         + task.mAffiliatedTaskId);
4031                 sane = false;
4032                 break;
4033             }
4034             prev = cur;
4035             endIndex++;
4036             if (endIndex >= N) {
4037                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4038                         + ": last task " + prev);
4039                 sane = false;
4040                 break;
4041             }
4042         }
4043         if (sane) {
4044             if (endIndex < taskIndex) {
4045                 Slog.wtf(TAG, "Bad chain @" + endIndex
4046                         + ": did not extend to task " + task + " @" + taskIndex);
4047                 sane = false;
4048             }
4049         }
4050         if (sane) {
4051             // All looks good, we can just move all of the affiliated tasks
4052             // to the top.
4053             for (int i=topIndex; i<=endIndex; i++) {
4054                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4055                         + " from " + i + " to " + (i-topIndex));
4056                 TaskRecord cur = mRecentTasks.remove(i);
4057                 mRecentTasks.add(i-topIndex, cur);
4058             }
4059             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4060                     + " to " + endIndex);
4061             return true;
4062         }
4063
4064         // Whoops, couldn't do it.
4065         return false;
4066     }
4067
4068     final void addRecentTaskLocked(TaskRecord task) {
4069         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4070                 || task.mNextAffiliateTaskId != INVALID_TASK_ID
4071                 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4072
4073         int N = mRecentTasks.size();
4074         // Quick case: check if the top-most recent task is the same.
4075         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4076             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4077             return;
4078         }
4079         // Another quick case: check if this is part of a set of affiliated
4080         // tasks that are at the top.
4081         if (isAffiliated && N > 0 && task.inRecents
4082                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4083             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4084                     + " at top when adding " + task);
4085             return;
4086         }
4087         // Another quick case: never add voice sessions.
4088         if (task.voiceSession != null) {
4089             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4090             return;
4091         }
4092
4093         boolean needAffiliationFix = false;
4094
4095         // Slightly less quick case: the task is already in recents, so all we need
4096         // to do is move it.
4097         if (task.inRecents) {
4098             int taskIndex = mRecentTasks.indexOf(task);
4099             if (taskIndex >= 0) {
4100                 if (!isAffiliated) {
4101                     // Simple case: this is not an affiliated task, so we just move it to the front.
4102                     mRecentTasks.remove(taskIndex);
4103                     mRecentTasks.add(0, task);
4104                     notifyTaskPersisterLocked(task, false);
4105                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4106                             + " from " + taskIndex);
4107                     return;
4108                 } else {
4109                     // More complicated: need to keep all affiliated tasks together.
4110                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4111                         // All went well.
4112                         return;
4113                     }
4114
4115                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4116                     // everything and then go through our general path of adding a new task.
4117                     needAffiliationFix = true;
4118                 }
4119             } else {
4120                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4121                 needAffiliationFix = true;
4122             }
4123         }
4124
4125         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4126         trimRecentsForTaskLocked(task, true);
4127
4128         N = mRecentTasks.size();
4129         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4130             final TaskRecord tr = mRecentTasks.remove(N - 1);
4131             tr.removedFromRecents();
4132             N--;
4133         }
4134         task.inRecents = true;
4135         if (!isAffiliated || needAffiliationFix) {
4136             // If this is a simple non-affiliated task, or we had some failure trying to
4137             // handle it as part of an affilated task, then just place it at the top.
4138             mRecentTasks.add(0, task);
4139         } else if (isAffiliated) {
4140             // If this is a new affiliated task, then move all of the affiliated tasks
4141             // to the front and insert this new one.
4142             TaskRecord other = task.mNextAffiliate;
4143             if (other == null) {
4144                 other = task.mPrevAffiliate;
4145             }
4146             if (other != null) {
4147                 int otherIndex = mRecentTasks.indexOf(other);
4148                 if (otherIndex >= 0) {
4149                     // Insert new task at appropriate location.
4150                     int taskIndex;
4151                     if (other == task.mNextAffiliate) {
4152                         // We found the index of our next affiliation, which is who is
4153                         // before us in the list, so add after that point.
4154                         taskIndex = otherIndex+1;
4155                     } else {
4156                         // We found the index of our previous affiliation, which is who is
4157                         // after us in the list, so add at their position.
4158                         taskIndex = otherIndex;
4159                     }
4160                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4161                             + taskIndex + ": " + task);
4162                     mRecentTasks.add(taskIndex, task);
4163
4164                     // Now move everything to the front.
4165                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4166                         // All went well.
4167                         return;
4168                     }
4169
4170                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4171                     // everything and then go through our general path of adding a new task.
4172                     needAffiliationFix = true;
4173                 } else {
4174                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4175                             + other);
4176                     needAffiliationFix = true;
4177                 }
4178             } else {
4179                 if (DEBUG_RECENTS) Slog.d(TAG,
4180                         "addRecent: adding affiliated task without next/prev:" + task);
4181                 needAffiliationFix = true;
4182             }
4183         }
4184         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4185
4186         if (needAffiliationFix) {
4187             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4188             cleanupRecentTasksLocked(task.userId);
4189         }
4190     }
4191
4192     /**
4193      * If needed, remove oldest existing entries in recents that are for the same kind
4194      * of task as the given one.
4195      */
4196     int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4197         int N = mRecentTasks.size();
4198         final Intent intent = task.intent;
4199         final boolean document = intent != null && intent.isDocument();
4200
4201         int maxRecents = task.maxRecents - 1;
4202         for (int i=0; i<N; i++) {
4203             final TaskRecord tr = mRecentTasks.get(i);
4204             if (task != tr) {
4205                 if (task.userId != tr.userId) {
4206                     continue;
4207                 }
4208                 if (i > MAX_RECENT_BITMAPS) {
4209                     tr.freeLastThumbnail();
4210                 }
4211                 final Intent trIntent = tr.intent;
4212                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4213                     (intent == null || !intent.filterEquals(trIntent))) {
4214                     continue;
4215                 }
4216                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4217                 if (document && trIsDocument) {
4218                     // These are the same document activity (not necessarily the same doc).
4219                     if (maxRecents > 0) {
4220                         --maxRecents;
4221                         continue;
4222                     }
4223                     // Hit the maximum number of documents for this task. Fall through
4224                     // and remove this document from recents.
4225                 } else if (document || trIsDocument) {
4226                     // Only one of these is a document. Not the droid we're looking for.
4227                     continue;
4228                 }
4229             }
4230
4231             if (!doTrim) {
4232                 // If the caller is not actually asking for a trim, just tell them we reached
4233                 // a point where the trim would happen.
4234                 return i;
4235             }
4236
4237             // Either task and tr are the same or, their affinities match or their intents match
4238             // and neither of them is a document, or they are documents using the same activity
4239             // and their maxRecents has been reached.
4240             tr.disposeThumbnail();
4241             mRecentTasks.remove(i);
4242             if (task != tr) {
4243                 tr.removedFromRecents();
4244             }
4245             i--;
4246             N--;
4247             if (task.intent == null) {
4248                 // If the new recent task we are adding is not fully
4249                 // specified, then replace it with the existing recent task.
4250                 task = tr;
4251             }
4252             notifyTaskPersisterLocked(tr, false);
4253         }
4254
4255         return -1;
4256     }
4257
4258     @Override
4259     public void reportActivityFullyDrawn(IBinder token) {
4260         synchronized (this) {
4261             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4262             if (r == null) {
4263                 return;
4264             }
4265             r.reportFullyDrawnLocked();
4266         }
4267     }
4268
4269     @Override
4270     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4271         synchronized (this) {
4272             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4273             if (r == null) {
4274                 return;
4275             }
4276             final long origId = Binder.clearCallingIdentity();
4277             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4278             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4279                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4280             if (config != null) {
4281                 r.frozenBeforeDestroy = true;
4282                 if (!updateConfigurationLocked(config, r, false, false)) {
4283                     mStackSupervisor.resumeTopActivitiesLocked();
4284                 }
4285             }
4286             Binder.restoreCallingIdentity(origId);
4287         }
4288     }
4289
4290     @Override
4291     public int getRequestedOrientation(IBinder token) {
4292         synchronized (this) {
4293             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4294             if (r == null) {
4295                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4296             }
4297             return mWindowManager.getAppOrientation(r.appToken);
4298         }
4299     }
4300
4301     /**
4302      * This is the internal entry point for handling Activity.finish().
4303      *
4304      * @param token The Binder token referencing the Activity we want to finish.
4305      * @param resultCode Result code, if any, from this Activity.
4306      * @param resultData Result data (Intent), if any, from this Activity.
4307      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4308      *            the root Activity in the task.
4309      *
4310      * @return Returns true if the activity successfully finished, or false if it is still running.
4311      */
4312     @Override
4313     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4314             boolean finishTask) {
4315         // Refuse possible leaked file descriptors
4316         if (resultData != null && resultData.hasFileDescriptors() == true) {
4317             throw new IllegalArgumentException("File descriptors passed in Intent");
4318         }
4319
4320         synchronized(this) {
4321             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4322             if (r == null) {
4323                 return true;
4324             }
4325             // Keep track of the root activity of the task before we finish it
4326             TaskRecord tr = r.task;
4327             ActivityRecord rootR = tr.getRootActivity();
4328             if (rootR == null) {
4329                 Slog.w(TAG, "Finishing task with all activities already finished");
4330             }
4331             // Do not allow task to finish in Lock Task mode.
4332             if (tr == mStackSupervisor.mLockTaskModeTask) {
4333                 if (rootR == r) {
4334                     Slog.i(TAG, "Not finishing task in lock task mode");
4335                     mStackSupervisor.showLockTaskToast();
4336                     return false;
4337                 }
4338             }
4339             if (mController != null) {
4340                 // Find the first activity that is not finishing.
4341                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4342                 if (next != null) {
4343                     // ask watcher if this is allowed
4344                     boolean resumeOK = true;
4345                     try {
4346                         resumeOK = mController.activityResuming(next.packageName);
4347                     } catch (RemoteException e) {
4348                         mController = null;
4349                         Watchdog.getInstance().setActivityController(null);
4350                     }
4351
4352                     if (!resumeOK) {
4353                         Slog.i(TAG, "Not finishing activity because controller resumed");
4354                         return false;
4355                     }
4356                 }
4357             }
4358             final long origId = Binder.clearCallingIdentity();
4359             try {
4360                 boolean res;
4361                 if (finishTask && r == rootR) {
4362                     // If requested, remove the task that is associated to this activity only if it
4363                     // was the root activity in the task. The result code and data is ignored
4364                     // because we don't support returning them across task boundaries.
4365                     res = removeTaskByIdLocked(tr.taskId, false);
4366                     if (!res) {
4367                         Slog.i(TAG, "Removing task failed to finish activity");
4368                     }
4369                 } else {
4370                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4371                             resultData, "app-request", true);
4372                     if (!res) {
4373                         Slog.i(TAG, "Failed to finish by app-request");
4374                     }
4375                 }
4376                 return res;
4377             } finally {
4378                 Binder.restoreCallingIdentity(origId);
4379             }
4380         }
4381     }
4382
4383     @Override
4384     public final void finishHeavyWeightApp() {
4385         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4386                 != PackageManager.PERMISSION_GRANTED) {
4387             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4388                     + Binder.getCallingPid()
4389                     + ", uid=" + Binder.getCallingUid()
4390                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4391             Slog.w(TAG, msg);
4392             throw new SecurityException(msg);
4393         }
4394
4395         synchronized(this) {
4396             if (mHeavyWeightProcess == null) {
4397                 return;
4398             }
4399
4400             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4401                     mHeavyWeightProcess.activities);
4402             for (int i=0; i<activities.size(); i++) {
4403                 ActivityRecord r = activities.get(i);
4404                 if (!r.finishing) {
4405                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4406                             null, "finish-heavy", true);
4407                 }
4408             }
4409
4410             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4411                     mHeavyWeightProcess.userId, 0));
4412             mHeavyWeightProcess = null;
4413         }
4414     }
4415
4416     @Override
4417     public void crashApplication(int uid, int initialPid, String packageName,
4418             String message) {
4419         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4420                 != PackageManager.PERMISSION_GRANTED) {
4421             String msg = "Permission Denial: crashApplication() from pid="
4422                     + Binder.getCallingPid()
4423                     + ", uid=" + Binder.getCallingUid()
4424                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4425             Slog.w(TAG, msg);
4426             throw new SecurityException(msg);
4427         }
4428
4429         synchronized(this) {
4430             ProcessRecord proc = null;
4431
4432             // Figure out which process to kill.  We don't trust that initialPid
4433             // still has any relation to current pids, so must scan through the
4434             // list.
4435             synchronized (mPidsSelfLocked) {
4436                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4437                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4438                     if (p.uid != uid) {
4439                         continue;
4440                     }
4441                     if (p.pid == initialPid) {
4442                         proc = p;
4443                         break;
4444                     }
4445                     if (p.pkgList.containsKey(packageName)) {
4446                         proc = p;
4447                     }
4448                 }
4449             }
4450
4451             if (proc == null) {
4452                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4453                         + " initialPid=" + initialPid
4454                         + " packageName=" + packageName);
4455                 return;
4456             }
4457
4458             if (proc.thread != null) {
4459                 if (proc.pid == Process.myPid()) {
4460                     Log.w(TAG, "crashApplication: trying to crash self!");
4461                     return;
4462                 }
4463                 long ident = Binder.clearCallingIdentity();
4464                 try {
4465                     proc.thread.scheduleCrash(message);
4466                 } catch (RemoteException e) {
4467                 }
4468                 Binder.restoreCallingIdentity(ident);
4469             }
4470         }
4471     }
4472
4473     @Override
4474     public final void finishSubActivity(IBinder token, String resultWho,
4475             int requestCode) {
4476         synchronized(this) {
4477             final long origId = Binder.clearCallingIdentity();
4478             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4479             if (r != null) {
4480                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4481             }
4482             Binder.restoreCallingIdentity(origId);
4483         }
4484     }
4485
4486     @Override
4487     public boolean finishActivityAffinity(IBinder token) {
4488         synchronized(this) {
4489             final long origId = Binder.clearCallingIdentity();
4490             try {
4491                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4492
4493                 ActivityRecord rootR = r.task.getRootActivity();
4494                 // Do not allow task to finish in Lock Task mode.
4495                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4496                     if (rootR == r) {
4497                         mStackSupervisor.showLockTaskToast();
4498                         return false;
4499                     }
4500                 }
4501                 boolean res = false;
4502                 if (r != null) {
4503                     res = r.task.stack.finishActivityAffinityLocked(r);
4504                 }
4505                 return res;
4506             } finally {
4507                 Binder.restoreCallingIdentity(origId);
4508             }
4509         }
4510     }
4511
4512     @Override
4513     public void finishVoiceTask(IVoiceInteractionSession session) {
4514         synchronized(this) {
4515             final long origId = Binder.clearCallingIdentity();
4516             try {
4517                 mStackSupervisor.finishVoiceTask(session);
4518             } finally {
4519                 Binder.restoreCallingIdentity(origId);
4520             }
4521         }
4522
4523     }
4524
4525     @Override
4526     public boolean releaseActivityInstance(IBinder token) {
4527         synchronized(this) {
4528             final long origId = Binder.clearCallingIdentity();
4529             try {
4530                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4531                 if (r.task == null || r.task.stack == null) {
4532                     return false;
4533                 }
4534                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4535             } finally {
4536                 Binder.restoreCallingIdentity(origId);
4537             }
4538         }
4539     }
4540
4541     @Override
4542     public void releaseSomeActivities(IApplicationThread appInt) {
4543         synchronized(this) {
4544             final long origId = Binder.clearCallingIdentity();
4545             try {
4546                 ProcessRecord app = getRecordForAppLocked(appInt);
4547                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4548             } finally {
4549                 Binder.restoreCallingIdentity(origId);
4550             }
4551         }
4552     }
4553
4554     @Override
4555     public boolean willActivityBeVisible(IBinder token) {
4556         synchronized(this) {
4557             ActivityStack stack = ActivityRecord.getStackLocked(token);
4558             if (stack != null) {
4559                 return stack.willActivityBeVisibleLocked(token);
4560             }
4561             return false;
4562         }
4563     }
4564
4565     @Override
4566     public void overridePendingTransition(IBinder token, String packageName,
4567             int enterAnim, int exitAnim) {
4568         synchronized(this) {
4569             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4570             if (self == null) {
4571                 return;
4572             }
4573
4574             final long origId = Binder.clearCallingIdentity();
4575
4576             if (self.state == ActivityState.RESUMED
4577                     || self.state == ActivityState.PAUSING) {
4578                 mWindowManager.overridePendingAppTransition(packageName,
4579                         enterAnim, exitAnim, null);
4580             }
4581
4582             Binder.restoreCallingIdentity(origId);
4583         }
4584     }
4585
4586     /**
4587      * Main function for removing an existing process from the activity manager
4588      * as a result of that process going away.  Clears out all connections
4589      * to the process.
4590      */
4591     private final void handleAppDiedLocked(ProcessRecord app,
4592             boolean restarting, boolean allowRestart) {
4593         int pid = app.pid;
4594         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4595         if (!kept && !restarting) {
4596             removeLruProcessLocked(app);
4597             if (pid > 0) {
4598                 ProcessList.remove(pid);
4599             }
4600         }
4601
4602         if (mProfileProc == app) {
4603             clearProfilerLocked();
4604         }
4605
4606         // Remove this application's activities from active lists.
4607         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4608
4609         app.activities.clear();
4610
4611         if (app.instrumentationClass != null) {
4612             Slog.w(TAG, "Crash of app " + app.processName
4613                   + " running instrumentation " + app.instrumentationClass);
4614             Bundle info = new Bundle();
4615             info.putString("shortMsg", "Process crashed.");
4616             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4617         }
4618
4619         if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4620             // If there was nothing to resume, and we are not already
4621             // restarting this process, but there is a visible activity that
4622             // is hosted by the process...  then make sure all visible
4623             // activities are running, taking care of restarting this
4624             // process.
4625             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4626         }
4627     }
4628
4629     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4630         IBinder threadBinder = thread.asBinder();
4631         // Find the application record.
4632         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4633             ProcessRecord rec = mLruProcesses.get(i);
4634             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4635                 return i;
4636             }
4637         }
4638         return -1;
4639     }
4640
4641     final ProcessRecord getRecordForAppLocked(
4642             IApplicationThread thread) {
4643         if (thread == null) {
4644             return null;
4645         }
4646
4647         int appIndex = getLRURecordIndexForAppLocked(thread);
4648         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4649     }
4650
4651     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4652         // If there are no longer any background processes running,
4653         // and the app that died was not running instrumentation,
4654         // then tell everyone we are now low on memory.
4655         boolean haveBg = false;
4656         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657             ProcessRecord rec = mLruProcesses.get(i);
4658             if (rec.thread != null
4659                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4660                 haveBg = true;
4661                 break;
4662             }
4663         }
4664
4665         if (!haveBg) {
4666             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4667             if (doReport) {
4668                 long now = SystemClock.uptimeMillis();
4669                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4670                     doReport = false;
4671                 } else {
4672                     mLastMemUsageReportTime = now;
4673                 }
4674             }
4675             final ArrayList<ProcessMemInfo> memInfos
4676                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4677             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4678             long now = SystemClock.uptimeMillis();
4679             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680                 ProcessRecord rec = mLruProcesses.get(i);
4681                 if (rec == dyingProc || rec.thread == null) {
4682                     continue;
4683                 }
4684                 if (doReport) {
4685                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4686                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4687                 }
4688                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4689                     // The low memory report is overriding any current
4690                     // state for a GC request.  Make sure to do
4691                     // heavy/important/visible/foreground processes first.
4692                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4693                         rec.lastRequestedGc = 0;
4694                     } else {
4695                         rec.lastRequestedGc = rec.lastLowMemory;
4696                     }
4697                     rec.reportLowMemory = true;
4698                     rec.lastLowMemory = now;
4699                     mProcessesToGc.remove(rec);
4700                     addProcessToGcListLocked(rec);
4701                 }
4702             }
4703             if (doReport) {
4704                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4705                 mHandler.sendMessage(msg);
4706             }
4707             scheduleAppGcsLocked();
4708         }
4709     }
4710
4711     final void appDiedLocked(ProcessRecord app) {
4712        appDiedLocked(app, app.pid, app.thread, false);
4713     }
4714
4715     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4716             boolean fromBinderDied) {
4717         // First check if this ProcessRecord is actually active for the pid.
4718         synchronized (mPidsSelfLocked) {
4719             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4720             if (curProc != app) {
4721                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4722                 return;
4723             }
4724         }
4725
4726         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4727         synchronized (stats) {
4728             stats.noteProcessDiedLocked(app.info.uid, pid);
4729         }
4730
4731         if (!app.killed) {
4732             if (!fromBinderDied) {
4733                 Process.killProcessQuiet(pid);
4734             }
4735             Process.killProcessGroup(app.info.uid, pid);
4736             app.killed = true;
4737         }
4738
4739         // Clean up already done if the process has been re-started.
4740         if (app.pid == pid && app.thread != null &&
4741                 app.thread.asBinder() == thread.asBinder()) {
4742             boolean doLowMem = app.instrumentationClass == null;
4743             boolean doOomAdj = doLowMem;
4744             if (!app.killedByAm) {
4745                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4746                         + ") has died");
4747                 mAllowLowerMemLevel = true;
4748             } else {
4749                 // Note that we always want to do oom adj to update our state with the
4750                 // new number of procs.
4751                 mAllowLowerMemLevel = false;
4752                 doLowMem = false;
4753             }
4754             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4755             if (DEBUG_CLEANUP) Slog.v(
4756                 TAG, "Dying app: " + app + ", pid: " + pid
4757                 + ", thread: " + thread.asBinder());
4758             handleAppDiedLocked(app, false, true);
4759
4760             if (doOomAdj) {
4761                 updateOomAdjLocked();
4762             }
4763             if (doLowMem) {
4764                 doLowMemReportIfNeededLocked(app);
4765             }
4766         } else if (app.pid != pid) {
4767             // A new process has already been started.
4768             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4769                     + ") has died and restarted (pid " + app.pid + ").");
4770             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4771         } else if (DEBUG_PROCESSES) {
4772             Slog.d(TAG, "Received spurious death notification for thread "
4773                     + thread.asBinder());
4774         }
4775     }
4776
4777     /**
4778      * If a stack trace dump file is configured, dump process stack traces.
4779      * @param clearTraces causes the dump file to be erased prior to the new
4780      *    traces being written, if true; when false, the new traces will be
4781      *    appended to any existing file content.
4782      * @param firstPids of dalvik VM processes to dump stack traces for first
4783      * @param lastPids of dalvik VM processes to dump stack traces for last
4784      * @param nativeProcs optional list of native process names to dump stack crawls
4785      * @return file containing stack traces, or null if no dump file is configured
4786      */
4787     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4788             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4789         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4790         if (tracesPath == null || tracesPath.length() == 0) {
4791             return null;
4792         }
4793
4794         File tracesFile = new File(tracesPath);
4795         try {
4796             File tracesDir = tracesFile.getParentFile();
4797             if (!tracesDir.exists()) {
4798                 tracesDir.mkdirs();
4799                 if (!SELinux.restorecon(tracesDir)) {
4800                     return null;
4801                 }
4802             }
4803             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4804
4805             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4806             tracesFile.createNewFile();
4807             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4808         } catch (IOException e) {
4809             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4810             return null;
4811         }
4812
4813         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4814         return tracesFile;
4815     }
4816
4817     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4818             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4819         // Use a FileObserver to detect when traces finish writing.
4820         // The order of traces is considered important to maintain for legibility.
4821         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4822             @Override
4823             public synchronized void onEvent(int event, String path) { notify(); }
4824         };
4825
4826         try {
4827             observer.startWatching();
4828
4829             // First collect all of the stacks of the most important pids.
4830             if (firstPids != null) {
4831                 try {
4832                     int num = firstPids.size();
4833                     for (int i = 0; i < num; i++) {
4834                         synchronized (observer) {
4835                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4836                             observer.wait(200);  // Wait for write-close, give up after 200msec
4837                         }
4838                     }
4839                 } catch (InterruptedException e) {
4840                     Slog.wtf(TAG, e);
4841                 }
4842             }
4843
4844             // Next collect the stacks of the native pids
4845             if (nativeProcs != null) {
4846                 int[] pids = Process.getPidsForCommands(nativeProcs);
4847                 if (pids != null) {
4848                     for (int pid : pids) {
4849                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4850                     }
4851                 }
4852             }
4853
4854             // Lastly, measure CPU usage.
4855             if (processCpuTracker != null) {
4856                 processCpuTracker.init();
4857                 System.gc();
4858                 processCpuTracker.update();
4859                 try {
4860                     synchronized (processCpuTracker) {
4861                         processCpuTracker.wait(500); // measure over 1/2 second.
4862                     }
4863                 } catch (InterruptedException e) {
4864                 }
4865                 processCpuTracker.update();
4866
4867                 // We'll take the stack crawls of just the top apps using CPU.
4868                 final int N = processCpuTracker.countWorkingStats();
4869                 int numProcs = 0;
4870                 for (int i=0; i<N && numProcs<5; i++) {
4871                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4872                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4873                         numProcs++;
4874                         try {
4875                             synchronized (observer) {
4876                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4877                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4878                             }
4879                         } catch (InterruptedException e) {
4880                             Slog.wtf(TAG, e);
4881                         }
4882
4883                     }
4884                 }
4885             }
4886         } finally {
4887             observer.stopWatching();
4888         }
4889     }
4890
4891     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4892         if (true || IS_USER_BUILD) {
4893             return;
4894         }
4895         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4896         if (tracesPath == null || tracesPath.length() == 0) {
4897             return;
4898         }
4899
4900         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4901         StrictMode.allowThreadDiskWrites();
4902         try {
4903             final File tracesFile = new File(tracesPath);
4904             final File tracesDir = tracesFile.getParentFile();
4905             final File tracesTmp = new File(tracesDir, "__tmp__");
4906             try {
4907                 if (!tracesDir.exists()) {
4908                     tracesDir.mkdirs();
4909                     if (!SELinux.restorecon(tracesDir.getPath())) {
4910                         return;
4911                     }
4912                 }
4913                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4914
4915                 if (tracesFile.exists()) {
4916                     tracesTmp.delete();
4917                     tracesFile.renameTo(tracesTmp);
4918                 }
4919                 StringBuilder sb = new StringBuilder();
4920                 Time tobj = new Time();
4921                 tobj.set(System.currentTimeMillis());
4922                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4923                 sb.append(": ");
4924                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4925                 sb.append(" since ");
4926                 sb.append(msg);
4927                 FileOutputStream fos = new FileOutputStream(tracesFile);
4928                 fos.write(sb.toString().getBytes());
4929                 if (app == null) {
4930                     fos.write("\n*** No application process!".getBytes());
4931                 }
4932                 fos.close();
4933                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4934             } catch (IOException e) {
4935                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4936                 return;
4937             }
4938
4939             if (app != null) {
4940                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4941                 firstPids.add(app.pid);
4942                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4943             }
4944
4945             File lastTracesFile = null;
4946             File curTracesFile = null;
4947             for (int i=9; i>=0; i--) {
4948                 String name = String.format(Locale.US, "slow%02d.txt", i);
4949                 curTracesFile = new File(tracesDir, name);
4950                 if (curTracesFile.exists()) {
4951                     if (lastTracesFile != null) {
4952                         curTracesFile.renameTo(lastTracesFile);
4953                     } else {
4954                         curTracesFile.delete();
4955                     }
4956                 }
4957                 lastTracesFile = curTracesFile;
4958             }
4959             tracesFile.renameTo(curTracesFile);
4960             if (tracesTmp.exists()) {
4961                 tracesTmp.renameTo(tracesFile);
4962             }
4963         } finally {
4964             StrictMode.setThreadPolicy(oldPolicy);
4965         }
4966     }
4967
4968     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4969             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4970         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4971         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4972
4973         if (mController != null) {
4974             try {
4975                 // 0 == continue, -1 = kill process immediately
4976                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4977                 if (res < 0 && app.pid != MY_PID) {
4978                     app.kill("anr", true);
4979                 }
4980             } catch (RemoteException e) {
4981                 mController = null;
4982                 Watchdog.getInstance().setActivityController(null);
4983             }
4984         }
4985
4986         long anrTime = SystemClock.uptimeMillis();
4987         if (MONITOR_CPU_USAGE) {
4988             updateCpuStatsNow();
4989         }
4990
4991         synchronized (this) {
4992             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4993             if (mShuttingDown) {
4994                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4995                 return;
4996             } else if (app.notResponding) {
4997                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4998                 return;
4999             } else if (app.crashing) {
5000                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5001                 return;
5002             }
5003
5004             // In case we come through here for the same app before completing
5005             // this one, mark as anring now so we will bail out.
5006             app.notResponding = true;
5007
5008             // Log the ANR to the event log.
5009             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5010                     app.processName, app.info.flags, annotation);
5011
5012             // Dump thread traces as quickly as we can, starting with "interesting" processes.
5013             firstPids.add(app.pid);
5014
5015             int parentPid = app.pid;
5016             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5017             if (parentPid != app.pid) firstPids.add(parentPid);
5018
5019             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5020
5021             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5022                 ProcessRecord r = mLruProcesses.get(i);
5023                 if (r != null && r.thread != null) {
5024                     int pid = r.pid;
5025                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5026                         if (r.persistent) {
5027                             firstPids.add(pid);
5028                         } else {
5029                             lastPids.put(pid, Boolean.TRUE);
5030                         }
5031                     }
5032                 }
5033             }
5034         }
5035
5036         // Log the ANR to the main log.
5037         StringBuilder info = new StringBuilder();
5038         info.setLength(0);
5039         info.append("ANR in ").append(app.processName);
5040         if (activity != null && activity.shortComponentName != null) {
5041             info.append(" (").append(activity.shortComponentName).append(")");
5042         }
5043         info.append("\n");
5044         info.append("PID: ").append(app.pid).append("\n");
5045         if (annotation != null) {
5046             info.append("Reason: ").append(annotation).append("\n");
5047         }
5048         if (parent != null && parent != activity) {
5049             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5050         }
5051
5052         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5053
5054         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5055                 NATIVE_STACKS_OF_INTEREST);
5056
5057         String cpuInfo = null;
5058         if (MONITOR_CPU_USAGE) {
5059             updateCpuStatsNow();
5060             synchronized (mProcessCpuTracker) {
5061                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5062             }
5063             info.append(processCpuTracker.printCurrentLoad());
5064             info.append(cpuInfo);
5065         }
5066
5067         info.append(processCpuTracker.printCurrentState(anrTime));
5068
5069         Slog.e(TAG, info.toString());
5070         if (tracesFile == null) {
5071             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5072             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5073         }
5074
5075         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5076                 cpuInfo, tracesFile, null);
5077
5078         if (mController != null) {
5079             try {
5080                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5081                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5082                 if (res != 0) {
5083                     if (res < 0 && app.pid != MY_PID) {
5084                         app.kill("anr", true);
5085                     } else {
5086                         synchronized (this) {
5087                             mServices.scheduleServiceTimeoutLocked(app);
5088                         }
5089                     }
5090                     return;
5091                 }
5092             } catch (RemoteException e) {
5093                 mController = null;
5094                 Watchdog.getInstance().setActivityController(null);
5095             }
5096         }
5097
5098         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5099         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5100                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5101
5102         synchronized (this) {
5103             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5104
5105             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5106                 app.kill("bg anr", true);
5107                 return;
5108             }
5109
5110             // Set the app's notResponding state, and look up the errorReportReceiver
5111             makeAppNotRespondingLocked(app,
5112                     activity != null ? activity.shortComponentName : null,
5113                     annotation != null ? "ANR " + annotation : "ANR",
5114                     info.toString());
5115
5116             // Bring up the infamous App Not Responding dialog
5117             Message msg = Message.obtain();
5118             HashMap<String, Object> map = new HashMap<String, Object>();
5119             msg.what = SHOW_NOT_RESPONDING_MSG;
5120             msg.obj = map;
5121             msg.arg1 = aboveSystem ? 1 : 0;
5122             map.put("app", app);
5123             if (activity != null) {
5124                 map.put("activity", activity);
5125             }
5126
5127             mUiHandler.sendMessage(msg);
5128         }
5129     }
5130
5131     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5132         if (!mLaunchWarningShown) {
5133             mLaunchWarningShown = true;
5134             mUiHandler.post(new Runnable() {
5135                 @Override
5136                 public void run() {
5137                     synchronized (ActivityManagerService.this) {
5138                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5139                         d.show();
5140                         mUiHandler.postDelayed(new Runnable() {
5141                             @Override
5142                             public void run() {
5143                                 synchronized (ActivityManagerService.this) {
5144                                     d.dismiss();
5145                                     mLaunchWarningShown = false;
5146                                 }
5147                             }
5148                         }, 4000);
5149                     }
5150                 }
5151             });
5152         }
5153     }
5154
5155     @Override
5156     public boolean clearApplicationUserData(final String packageName,
5157             final IPackageDataObserver observer, int userId) {
5158         enforceNotIsolatedCaller("clearApplicationUserData");
5159         int uid = Binder.getCallingUid();
5160         int pid = Binder.getCallingPid();
5161         userId = handleIncomingUser(pid, uid,
5162                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5163         long callingId = Binder.clearCallingIdentity();
5164         try {
5165             IPackageManager pm = AppGlobals.getPackageManager();
5166             int pkgUid = -1;
5167             synchronized(this) {
5168                 try {
5169                     pkgUid = pm.getPackageUid(packageName, userId);
5170                 } catch (RemoteException e) {
5171                 }
5172                 if (pkgUid == -1) {
5173                     Slog.w(TAG, "Invalid packageName: " + packageName);
5174                     if (observer != null) {
5175                         try {
5176                             observer.onRemoveCompleted(packageName, false);
5177                         } catch (RemoteException e) {
5178                             Slog.i(TAG, "Observer no longer exists.");
5179                         }
5180                     }
5181                     return false;
5182                 }
5183                 if (uid == pkgUid || checkComponentPermission(
5184                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5185                         pid, uid, -1, true)
5186                         == PackageManager.PERMISSION_GRANTED) {
5187                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5188                 } else {
5189                     throw new SecurityException("PID " + pid + " does not have permission "
5190                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5191                                     + " of package " + packageName);
5192                 }
5193
5194                 // Remove all tasks match the cleared application package and user
5195                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5196                     final TaskRecord tr = mRecentTasks.get(i);
5197                     final String taskPackageName =
5198                             tr.getBaseIntent().getComponent().getPackageName();
5199                     if (tr.userId != userId) continue;
5200                     if (!taskPackageName.equals(packageName)) continue;
5201                     removeTaskByIdLocked(tr.taskId, false);
5202                 }
5203             }
5204
5205             try {
5206                 // Clear application user data
5207                 pm.clearApplicationUserData(packageName, observer, userId);
5208
5209                 synchronized(this) {
5210                     // Remove all permissions granted from/to this package
5211                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5212                 }
5213
5214                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5215                         Uri.fromParts("package", packageName, null));
5216                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5217                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5218                         null, null, 0, null, null, null, false, false, userId);
5219             } catch (RemoteException e) {
5220             }
5221         } finally {
5222             Binder.restoreCallingIdentity(callingId);
5223         }
5224         return true;
5225     }
5226
5227     @Override
5228     public void killBackgroundProcesses(final String packageName, int userId) {
5229         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5230                 != PackageManager.PERMISSION_GRANTED &&
5231                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5232                         != PackageManager.PERMISSION_GRANTED) {
5233             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5234                     + Binder.getCallingPid()
5235                     + ", uid=" + Binder.getCallingUid()
5236                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5237             Slog.w(TAG, msg);
5238             throw new SecurityException(msg);
5239         }
5240
5241         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5242                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5243         long callingId = Binder.clearCallingIdentity();
5244         try {
5245             IPackageManager pm = AppGlobals.getPackageManager();
5246             synchronized(this) {
5247                 int appId = -1;
5248                 try {
5249                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5250                 } catch (RemoteException e) {
5251                 }
5252                 if (appId == -1) {
5253                     Slog.w(TAG, "Invalid packageName: " + packageName);
5254                     return;
5255                 }
5256                 killPackageProcessesLocked(packageName, appId, userId,
5257                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5258             }
5259         } finally {
5260             Binder.restoreCallingIdentity(callingId);
5261         }
5262     }
5263
5264     @Override
5265     public void killAllBackgroundProcesses() {
5266         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5267                 != PackageManager.PERMISSION_GRANTED) {
5268             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5269                     + Binder.getCallingPid()
5270                     + ", uid=" + Binder.getCallingUid()
5271                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5272             Slog.w(TAG, msg);
5273             throw new SecurityException(msg);
5274         }
5275
5276         long callingId = Binder.clearCallingIdentity();
5277         try {
5278             synchronized(this) {
5279                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5280                 final int NP = mProcessNames.getMap().size();
5281                 for (int ip=0; ip<NP; ip++) {
5282                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5283                     final int NA = apps.size();
5284                     for (int ia=0; ia<NA; ia++) {
5285                         ProcessRecord app = apps.valueAt(ia);
5286                         if (app.persistent) {
5287                             // we don't kill persistent processes
5288                             continue;
5289                         }
5290                         if (app.removed) {
5291                             procs.add(app);
5292                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5293                             app.removed = true;
5294                             procs.add(app);
5295                         }
5296                     }
5297                 }
5298
5299                 int N = procs.size();
5300                 for (int i=0; i<N; i++) {
5301                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5302                 }
5303                 mAllowLowerMemLevel = true;
5304                 updateOomAdjLocked();
5305                 doLowMemReportIfNeededLocked(null);
5306             }
5307         } finally {
5308             Binder.restoreCallingIdentity(callingId);
5309         }
5310     }
5311
5312     @Override
5313     public void forceStopPackage(final String packageName, int userId) {
5314         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5315                 != PackageManager.PERMISSION_GRANTED) {
5316             String msg = "Permission Denial: forceStopPackage() from pid="
5317                     + Binder.getCallingPid()
5318                     + ", uid=" + Binder.getCallingUid()
5319                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5320             Slog.w(TAG, msg);
5321             throw new SecurityException(msg);
5322         }
5323         final int callingPid = Binder.getCallingPid();
5324         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5325                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5326         long callingId = Binder.clearCallingIdentity();
5327         try {
5328             IPackageManager pm = AppGlobals.getPackageManager();
5329             synchronized(this) {
5330                 int[] users = userId == UserHandle.USER_ALL
5331                         ? getUsersLocked() : new int[] { userId };
5332                 for (int user : users) {
5333                     int pkgUid = -1;
5334                     try {
5335                         pkgUid = pm.getPackageUid(packageName, user);
5336                     } catch (RemoteException e) {
5337                     }
5338                     if (pkgUid == -1) {
5339                         Slog.w(TAG, "Invalid packageName: " + packageName);
5340                         continue;
5341                     }
5342                     try {
5343                         pm.setPackageStoppedState(packageName, true, user);
5344                     } catch (RemoteException e) {
5345                     } catch (IllegalArgumentException e) {
5346                         Slog.w(TAG, "Failed trying to unstop package "
5347                                 + packageName + ": " + e);
5348                     }
5349                     if (isUserRunningLocked(user, false)) {
5350                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5351                     }
5352                 }
5353             }
5354         } finally {
5355             Binder.restoreCallingIdentity(callingId);
5356         }
5357     }
5358
5359     @Override
5360     public void addPackageDependency(String packageName) {
5361         synchronized (this) {
5362             int callingPid = Binder.getCallingPid();
5363             if (callingPid == Process.myPid()) {
5364                 //  Yeah, um, no.
5365                 return;
5366             }
5367             ProcessRecord proc;
5368             synchronized (mPidsSelfLocked) {
5369                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5370             }
5371             if (proc != null) {
5372                 if (proc.pkgDeps == null) {
5373                     proc.pkgDeps = new ArraySet<String>(1);
5374                 }
5375                 proc.pkgDeps.add(packageName);
5376             }
5377         }
5378     }
5379
5380     /*
5381      * The pkg name and app id have to be specified.
5382      */
5383     @Override
5384     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5385         if (pkg == null) {
5386             return;
5387         }
5388         // Make sure the uid is valid.
5389         if (appid < 0) {
5390             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5391             return;
5392         }
5393         int callerUid = Binder.getCallingUid();
5394         // Only the system server can kill an application
5395         if (callerUid == Process.SYSTEM_UID) {
5396             // Post an aysnc message to kill the application
5397             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5398             msg.arg1 = appid;
5399             msg.arg2 = 0;
5400             Bundle bundle = new Bundle();
5401             bundle.putString("pkg", pkg);
5402             bundle.putString("reason", reason);
5403             msg.obj = bundle;
5404             mHandler.sendMessage(msg);
5405         } else {
5406             throw new SecurityException(callerUid + " cannot kill pkg: " +
5407                     pkg);
5408         }
5409     }
5410
5411     @Override
5412     public void closeSystemDialogs(String reason) {
5413         enforceNotIsolatedCaller("closeSystemDialogs");
5414
5415         final int pid = Binder.getCallingPid();
5416         final int uid = Binder.getCallingUid();
5417         final long origId = Binder.clearCallingIdentity();
5418         try {
5419             synchronized (this) {
5420                 // Only allow this from foreground processes, so that background
5421                 // applications can't abuse it to prevent system UI from being shown.
5422                 if (uid >= Process.FIRST_APPLICATION_UID) {
5423                     ProcessRecord proc;
5424                     synchronized (mPidsSelfLocked) {
5425                         proc = mPidsSelfLocked.get(pid);
5426                     }
5427                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5428                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5429                                 + " from background process " + proc);
5430                         return;
5431                     }
5432                 }
5433                 closeSystemDialogsLocked(reason);
5434             }
5435         } finally {
5436             Binder.restoreCallingIdentity(origId);
5437         }
5438     }
5439
5440     void closeSystemDialogsLocked(String reason) {
5441         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5442         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5443                 | Intent.FLAG_RECEIVER_FOREGROUND);
5444         if (reason != null) {
5445             intent.putExtra("reason", reason);
5446         }
5447         mWindowManager.closeSystemDialogs(reason);
5448
5449         mStackSupervisor.closeSystemDialogsLocked();
5450
5451         broadcastIntentLocked(null, null, intent, null,
5452                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5453                 Process.SYSTEM_UID, UserHandle.USER_ALL);
5454     }
5455
5456     @Override
5457     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5458         enforceNotIsolatedCaller("getProcessMemoryInfo");
5459         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5460         for (int i=pids.length-1; i>=0; i--) {
5461             ProcessRecord proc;
5462             int oomAdj;
5463             synchronized (this) {
5464                 synchronized (mPidsSelfLocked) {
5465                     proc = mPidsSelfLocked.get(pids[i]);
5466                     oomAdj = proc != null ? proc.setAdj : 0;
5467                 }
5468             }
5469             infos[i] = new Debug.MemoryInfo();
5470             Debug.getMemoryInfo(pids[i], infos[i]);
5471             if (proc != null) {
5472                 synchronized (this) {
5473                     if (proc.thread != null && proc.setAdj == oomAdj) {
5474                         // Record this for posterity if the process has been stable.
5475                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5476                                 infos[i].getTotalUss(), false, proc.pkgList);
5477                     }
5478                 }
5479             }
5480         }
5481         return infos;
5482     }
5483
5484     @Override
5485     public long[] getProcessPss(int[] pids) {
5486         enforceNotIsolatedCaller("getProcessPss");
5487         long[] pss = new long[pids.length];
5488         for (int i=pids.length-1; i>=0; i--) {
5489             ProcessRecord proc;
5490             int oomAdj;
5491             synchronized (this) {
5492                 synchronized (mPidsSelfLocked) {
5493                     proc = mPidsSelfLocked.get(pids[i]);
5494                     oomAdj = proc != null ? proc.setAdj : 0;
5495                 }
5496             }
5497             long[] tmpUss = new long[1];
5498             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5499             if (proc != null) {
5500                 synchronized (this) {
5501                     if (proc.thread != null && proc.setAdj == oomAdj) {
5502                         // Record this for posterity if the process has been stable.
5503                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5504                     }
5505                 }
5506             }
5507         }
5508         return pss;
5509     }
5510
5511     @Override
5512     public void killApplicationProcess(String processName, int uid) {
5513         if (processName == null) {
5514             return;
5515         }
5516
5517         int callerUid = Binder.getCallingUid();
5518         // Only the system server can kill an application
5519         if (callerUid == Process.SYSTEM_UID) {
5520             synchronized (this) {
5521                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5522                 if (app != null && app.thread != null) {
5523                     try {
5524                         app.thread.scheduleSuicide();
5525                     } catch (RemoteException e) {
5526                         // If the other end already died, then our work here is done.
5527                     }
5528                 } else {
5529                     Slog.w(TAG, "Process/uid not found attempting kill of "
5530                             + processName + " / " + uid);
5531                 }
5532             }
5533         } else {
5534             throw new SecurityException(callerUid + " cannot kill app process: " +
5535                     processName);
5536         }
5537     }
5538
5539     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5540         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5541                 false, true, false, false, UserHandle.getUserId(uid), reason);
5542         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5543                 Uri.fromParts("package", packageName, null));
5544         if (!mProcessesReady) {
5545             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5546                     | Intent.FLAG_RECEIVER_FOREGROUND);
5547         }
5548         intent.putExtra(Intent.EXTRA_UID, uid);
5549         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5550         broadcastIntentLocked(null, null, intent,
5551                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5552                 false, false,
5553                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5554     }
5555
5556     private void forceStopUserLocked(int userId, String reason) {
5557         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5558         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5559         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5560                 | Intent.FLAG_RECEIVER_FOREGROUND);
5561         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5562         broadcastIntentLocked(null, null, intent,
5563                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5564                 false, false,
5565                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5566     }
5567
5568     private final boolean killPackageProcessesLocked(String packageName, int appId,
5569             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5570             boolean doit, boolean evenPersistent, String reason) {
5571         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5572
5573         // Remove all processes this package may have touched: all with the
5574         // same UID (except for the system or root user), and all whose name
5575         // matches the package name.
5576         final int NP = mProcessNames.getMap().size();
5577         for (int ip=0; ip<NP; ip++) {
5578             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5579             final int NA = apps.size();
5580             for (int ia=0; ia<NA; ia++) {
5581                 ProcessRecord app = apps.valueAt(ia);
5582                 if (app.persistent && !evenPersistent) {
5583                     // we don't kill persistent processes
5584                     continue;
5585                 }
5586                 if (app.removed) {
5587                     if (doit) {
5588                         procs.add(app);
5589                     }
5590                     continue;
5591                 }
5592
5593                 // Skip process if it doesn't meet our oom adj requirement.
5594                 if (app.setAdj < minOomAdj) {
5595                     continue;
5596                 }
5597
5598                 // If no package is specified, we call all processes under the
5599                 // give user id.
5600                 if (packageName == null) {
5601                     if (app.userId != userId) {
5602                         continue;
5603                     }
5604                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5605                         continue;
5606                     }
5607                 // Package has been specified, we want to hit all processes
5608                 // that match it.  We need to qualify this by the processes
5609                 // that are running under the specified app and user ID.
5610                 } else {
5611                     final boolean isDep = app.pkgDeps != null
5612                             && app.pkgDeps.contains(packageName);
5613                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5614                         continue;
5615                     }
5616                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5617                         continue;
5618                     }
5619                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5620                         continue;
5621                     }
5622                 }
5623
5624                 // Process has passed all conditions, kill it!
5625                 if (!doit) {
5626                     return true;
5627                 }
5628                 app.removed = true;
5629                 procs.add(app);
5630             }
5631         }
5632
5633         int N = procs.size();
5634         for (int i=0; i<N; i++) {
5635             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5636         }
5637         updateOomAdjLocked();
5638         return N > 0;
5639     }
5640
5641     private final boolean forceStopPackageLocked(String name, int appId,
5642             boolean callerWillRestart, boolean purgeCache, boolean doit,
5643             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5644         int i;
5645         int N;
5646
5647         if (userId == UserHandle.USER_ALL && name == null) {
5648             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5649         }
5650
5651         if (appId < 0 && name != null) {
5652             try {
5653                 appId = UserHandle.getAppId(
5654                         AppGlobals.getPackageManager().getPackageUid(name, 0));
5655             } catch (RemoteException e) {
5656             }
5657         }
5658
5659         if (doit) {
5660             if (name != null) {
5661                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5662                         + " user=" + userId + ": " + reason);
5663             } else {
5664                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5665             }
5666
5667             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5668             for (int ip=pmap.size()-1; ip>=0; ip--) {
5669                 SparseArray<Long> ba = pmap.valueAt(ip);
5670                 for (i=ba.size()-1; i>=0; i--) {
5671                     boolean remove = false;
5672                     final int entUid = ba.keyAt(i);
5673                     if (name != null) {
5674                         if (userId == UserHandle.USER_ALL) {
5675                             if (UserHandle.getAppId(entUid) == appId) {
5676                                 remove = true;
5677                             }
5678                         } else {
5679                             if (entUid == UserHandle.getUid(userId, appId)) {
5680                                 remove = true;
5681                             }
5682                         }
5683                     } else if (UserHandle.getUserId(entUid) == userId) {
5684                         remove = true;
5685                     }
5686                     if (remove) {
5687                         ba.removeAt(i);
5688                     }
5689                 }
5690                 if (ba.size() == 0) {
5691                     pmap.removeAt(ip);
5692                 }
5693             }
5694         }
5695
5696         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5697                 -100, callerWillRestart, true, doit, evenPersistent,
5698                 name == null ? ("stop user " + userId) : ("stop " + name));
5699
5700         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5701             if (!doit) {
5702                 return true;
5703             }
5704             didSomething = true;
5705         }
5706
5707         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5708             if (!doit) {
5709                 return true;
5710             }
5711             didSomething = true;
5712         }
5713
5714         if (name == null) {
5715             // Remove all sticky broadcasts from this user.
5716             mStickyBroadcasts.remove(userId);
5717         }
5718
5719         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5720         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5721                 userId, providers)) {
5722             if (!doit) {
5723                 return true;
5724             }
5725             didSomething = true;
5726         }
5727         N = providers.size();
5728         for (i=0; i<N; i++) {
5729             removeDyingProviderLocked(null, providers.get(i), true);
5730         }
5731
5732         // Remove transient permissions granted from/to this package/user
5733         removeUriPermissionsForPackageLocked(name, userId, false);
5734
5735         if (name == null || uninstalling) {
5736             // Remove pending intents.  For now we only do this when force
5737             // stopping users, because we have some problems when doing this
5738             // for packages -- app widgets are not currently cleaned up for
5739             // such packages, so they can be left with bad pending intents.
5740             if (mIntentSenderRecords.size() > 0) {
5741                 Iterator<WeakReference<PendingIntentRecord>> it
5742                         = mIntentSenderRecords.values().iterator();
5743                 while (it.hasNext()) {
5744                     WeakReference<PendingIntentRecord> wpir = it.next();
5745                     if (wpir == null) {
5746                         it.remove();
5747                         continue;
5748                     }
5749                     PendingIntentRecord pir = wpir.get();
5750                     if (pir == null) {
5751                         it.remove();
5752                         continue;
5753                     }
5754                     if (name == null) {
5755                         // Stopping user, remove all objects for the user.
5756                         if (pir.key.userId != userId) {
5757                             // Not the same user, skip it.
5758                             continue;
5759                         }
5760                     } else {
5761                         if (UserHandle.getAppId(pir.uid) != appId) {
5762                             // Different app id, skip it.
5763                             continue;
5764                         }
5765                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5766                             // Different user, skip it.
5767                             continue;
5768                         }
5769                         if (!pir.key.packageName.equals(name)) {
5770                             // Different package, skip it.
5771                             continue;
5772                         }
5773                     }
5774                     if (!doit) {
5775                         return true;
5776                     }
5777                     didSomething = true;
5778                     it.remove();
5779                     pir.canceled = true;
5780                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5781                         pir.key.activity.pendingResults.remove(pir.ref);
5782                     }
5783                 }
5784             }
5785         }
5786
5787         if (doit) {
5788             if (purgeCache && name != null) {
5789                 AttributeCache ac = AttributeCache.instance();
5790                 if (ac != null) {
5791                     ac.removePackage(name);
5792                 }
5793             }
5794             if (mBooted) {
5795                 mStackSupervisor.resumeTopActivitiesLocked();
5796                 mStackSupervisor.scheduleIdleLocked();
5797             }
5798         }
5799
5800         return didSomething;
5801     }
5802
5803     private final boolean removeProcessLocked(ProcessRecord app,
5804             boolean callerWillRestart, boolean allowRestart, String reason) {
5805         final String name = app.processName;
5806         final int uid = app.uid;
5807         if (DEBUG_PROCESSES) Slog.d(
5808             TAG, "Force removing proc " + app.toShortString() + " (" + name
5809             + "/" + uid + ")");
5810
5811         mProcessNames.remove(name, uid);
5812         mIsolatedProcesses.remove(app.uid);
5813         if (mHeavyWeightProcess == app) {
5814             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5815                     mHeavyWeightProcess.userId, 0));
5816             mHeavyWeightProcess = null;
5817         }
5818         boolean needRestart = false;
5819         if (app.pid > 0 && app.pid != MY_PID) {
5820             int pid = app.pid;
5821             synchronized (mPidsSelfLocked) {
5822                 mPidsSelfLocked.remove(pid);
5823                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5824             }
5825             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5826             if (app.isolated) {
5827                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5828             }
5829             boolean willRestart = false;
5830             if (app.persistent && !app.isolated) {
5831                 if (!callerWillRestart) {
5832                     willRestart = true;
5833                 } else {
5834                     needRestart = true;
5835                 }
5836             }
5837             app.kill(reason, true);
5838             handleAppDiedLocked(app, willRestart, allowRestart);
5839             if (willRestart) {
5840                 removeLruProcessLocked(app);
5841                 addAppLocked(app.info, false, null /* ABI override */);
5842             }
5843         } else {
5844             mRemovedProcesses.add(app);
5845         }
5846
5847         return needRestart;
5848     }
5849
5850     private final void processStartTimedOutLocked(ProcessRecord app) {
5851         final int pid = app.pid;
5852         boolean gone = false;
5853         synchronized (mPidsSelfLocked) {
5854             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5855             if (knownApp != null && knownApp.thread == null) {
5856                 mPidsSelfLocked.remove(pid);
5857                 gone = true;
5858             }
5859         }
5860
5861         if (gone) {
5862             Slog.w(TAG, "Process " + app + " failed to attach");
5863             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5864                     pid, app.uid, app.processName);
5865             mProcessNames.remove(app.processName, app.uid);
5866             mIsolatedProcesses.remove(app.uid);
5867             if (mHeavyWeightProcess == app) {
5868                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5869                         mHeavyWeightProcess.userId, 0));
5870                 mHeavyWeightProcess = null;
5871             }
5872             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5873             if (app.isolated) {
5874                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5875             }
5876             // Take care of any launching providers waiting for this process.
5877             checkAppInLaunchingProvidersLocked(app, true);
5878             // Take care of any services that are waiting for the process.
5879             mServices.processStartTimedOutLocked(app);
5880             app.kill("start timeout", true);
5881             removeLruProcessLocked(app);
5882             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5883                 Slog.w(TAG, "Unattached app died before backup, skipping");
5884                 try {
5885                     IBackupManager bm = IBackupManager.Stub.asInterface(
5886                             ServiceManager.getService(Context.BACKUP_SERVICE));
5887                     bm.agentDisconnected(app.info.packageName);
5888                 } catch (RemoteException e) {
5889                     // Can't happen; the backup manager is local
5890                 }
5891             }
5892             if (isPendingBroadcastProcessLocked(pid)) {
5893                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5894                 skipPendingBroadcastLocked(pid);
5895             }
5896         } else {
5897             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5898         }
5899     }
5900
5901     private final boolean attachApplicationLocked(IApplicationThread thread,
5902             int pid) {
5903
5904         // Find the application record that is being attached...  either via
5905         // the pid if we are running in multiple processes, or just pull the
5906         // next app record if we are emulating process with anonymous threads.
5907         ProcessRecord app;
5908         if (pid != MY_PID && pid >= 0) {
5909             synchronized (mPidsSelfLocked) {
5910                 app = mPidsSelfLocked.get(pid);
5911             }
5912         } else {
5913             app = null;
5914         }
5915
5916         if (app == null) {
5917             Slog.w(TAG, "No pending application record for pid " + pid
5918                     + " (IApplicationThread " + thread + "); dropping process");
5919             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5920             if (pid > 0 && pid != MY_PID) {
5921                 Process.killProcessQuiet(pid);
5922                 //TODO: Process.killProcessGroup(app.info.uid, pid);
5923             } else {
5924                 try {
5925                     thread.scheduleExit();
5926                 } catch (Exception e) {
5927                     // Ignore exceptions.
5928                 }
5929             }
5930             return false;
5931         }
5932
5933         // If this application record is still attached to a previous
5934         // process, clean it up now.
5935         if (app.thread != null) {
5936             handleAppDiedLocked(app, true, true);
5937         }
5938
5939         // Tell the process all about itself.
5940
5941         if (localLOGV) Slog.v(
5942                 TAG, "Binding process pid " + pid + " to record " + app);
5943
5944         final String processName = app.processName;
5945         try {
5946             AppDeathRecipient adr = new AppDeathRecipient(
5947                     app, pid, thread);
5948             thread.asBinder().linkToDeath(adr, 0);
5949             app.deathRecipient = adr;
5950         } catch (RemoteException e) {
5951             app.resetPackageList(mProcessStats);
5952             startProcessLocked(app, "link fail", processName);
5953             return false;
5954         }
5955
5956         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5957
5958         app.makeActive(thread, mProcessStats);
5959         app.curAdj = app.setAdj = -100;
5960         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5961         app.forcingToForeground = null;
5962         updateProcessForegroundLocked(app, false, false);
5963         app.hasShownUi = false;
5964         app.debugging = false;
5965         app.cached = false;
5966         app.killedByAm = false;
5967
5968         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5969
5970         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5971         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5972
5973         if (!normalMode) {
5974             Slog.i(TAG, "Launching preboot mode app: " + app);
5975         }
5976
5977         if (localLOGV) Slog.v(
5978             TAG, "New app record " + app
5979             + " thread=" + thread.asBinder() + " pid=" + pid);
5980         try {
5981             int testMode = IApplicationThread.DEBUG_OFF;
5982             if (mDebugApp != null && mDebugApp.equals(processName)) {
5983                 testMode = mWaitForDebugger
5984                     ? IApplicationThread.DEBUG_WAIT
5985                     : IApplicationThread.DEBUG_ON;
5986                 app.debugging = true;
5987                 if (mDebugTransient) {
5988                     mDebugApp = mOrigDebugApp;
5989                     mWaitForDebugger = mOrigWaitForDebugger;
5990                 }
5991             }
5992             String profileFile = app.instrumentationProfileFile;
5993             ParcelFileDescriptor profileFd = null;
5994             int samplingInterval = 0;
5995             boolean profileAutoStop = false;
5996             if (mProfileApp != null && mProfileApp.equals(processName)) {
5997                 mProfileProc = app;
5998                 profileFile = mProfileFile;
5999                 profileFd = mProfileFd;
6000                 samplingInterval = mSamplingInterval;
6001                 profileAutoStop = mAutoStopProfiler;
6002             }
6003             boolean enableOpenGlTrace = false;
6004             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6005                 enableOpenGlTrace = true;
6006                 mOpenGlTraceApp = null;
6007             }
6008
6009             // If the app is being launched for restore or full backup, set it up specially
6010             boolean isRestrictedBackupMode = false;
6011             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6012                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6013                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6014                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6015             }
6016
6017             ensurePackageDexOpt(app.instrumentationInfo != null
6018                     ? app.instrumentationInfo.packageName
6019                     : app.info.packageName);
6020             if (app.instrumentationClass != null) {
6021                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6022             }
6023             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6024                     + processName + " with config " + mConfiguration);
6025             ApplicationInfo appInfo = app.instrumentationInfo != null
6026                     ? app.instrumentationInfo : app.info;
6027             app.compat = compatibilityInfoForPackageLocked(appInfo);
6028             if (profileFd != null) {
6029                 profileFd = profileFd.dup();
6030             }
6031             ProfilerInfo profilerInfo = profileFile == null ? null
6032                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6033             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6034                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6035                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6036                     isRestrictedBackupMode || !normalMode, app.persistent,
6037                     new Configuration(mConfiguration), app.compat,
6038                     getCommonServicesLocked(app.isolated),
6039                     mCoreSettingsObserver.getCoreSettingsLocked());
6040             updateLruProcessLocked(app, false, null);
6041             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6042         } catch (Exception e) {
6043             // todo: Yikes!  What should we do?  For now we will try to
6044             // start another process, but that could easily get us in
6045             // an infinite loop of restarting processes...
6046             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6047
6048             app.resetPackageList(mProcessStats);
6049             app.unlinkDeathRecipient();
6050             startProcessLocked(app, "bind fail", processName);
6051             return false;
6052         }
6053
6054         // Remove this record from the list of starting applications.
6055         mPersistentStartingProcesses.remove(app);
6056         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6057                 "Attach application locked removing on hold: " + app);
6058         mProcessesOnHold.remove(app);
6059
6060         boolean badApp = false;
6061         boolean didSomething = false;
6062
6063         // See if the top visible activity is waiting to run in this process...
6064         if (normalMode) {
6065             try {
6066                 if (mStackSupervisor.attachApplicationLocked(app)) {
6067                     didSomething = true;
6068                 }
6069             } catch (Exception e) {
6070                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6071                 badApp = true;
6072             }
6073         }
6074
6075         // Find any services that should be running in this process...
6076         if (!badApp) {
6077             try {
6078                 didSomething |= mServices.attachApplicationLocked(app, processName);
6079             } catch (Exception e) {
6080                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6081                 badApp = true;
6082             }
6083         }
6084
6085         // Check if a next-broadcast receiver is in this process...
6086         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6087             try {
6088                 didSomething |= sendPendingBroadcastsLocked(app);
6089             } catch (Exception e) {
6090                 // If the app died trying to launch the receiver we declare it 'bad'
6091                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6092                 badApp = true;
6093             }
6094         }
6095
6096         // Check whether the next backup agent is in this process...
6097         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6098             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6099             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6100             try {
6101                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6102                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6103                         mBackupTarget.backupMode);
6104             } catch (Exception e) {
6105                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6106                 badApp = true;
6107             }
6108         }
6109
6110         if (badApp) {
6111             app.kill("error during init", true);
6112             handleAppDiedLocked(app, false, true);
6113             return false;
6114         }
6115
6116         if (!didSomething) {
6117             updateOomAdjLocked();
6118         }
6119
6120         return true;
6121     }
6122
6123     @Override
6124     public final void attachApplication(IApplicationThread thread) {
6125         synchronized (this) {
6126             int callingPid = Binder.getCallingPid();
6127             final long origId = Binder.clearCallingIdentity();
6128             attachApplicationLocked(thread, callingPid);
6129             Binder.restoreCallingIdentity(origId);
6130         }
6131     }
6132
6133     @Override
6134     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6135         final long origId = Binder.clearCallingIdentity();
6136         synchronized (this) {
6137             ActivityStack stack = ActivityRecord.getStackLocked(token);
6138             if (stack != null) {
6139                 ActivityRecord r =
6140                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6141                 if (stopProfiling) {
6142                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6143                         try {
6144                             mProfileFd.close();
6145                         } catch (IOException e) {
6146                         }
6147                         clearProfilerLocked();
6148                     }
6149                 }
6150             }
6151         }
6152         Binder.restoreCallingIdentity(origId);
6153     }
6154
6155     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6156         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6157                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6158     }
6159
6160     void enableScreenAfterBoot() {
6161         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6162                 SystemClock.uptimeMillis());
6163         mWindowManager.enableScreenAfterBoot();
6164
6165         synchronized (this) {
6166             updateEventDispatchingLocked();
6167         }
6168     }
6169
6170     @Override
6171     public void showBootMessage(final CharSequence msg, final boolean always) {
6172         enforceNotIsolatedCaller("showBootMessage");
6173         mWindowManager.showBootMessage(msg, always);
6174     }
6175
6176     @Override
6177     public void keyguardWaitingForActivityDrawn() {
6178         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6179         final long token = Binder.clearCallingIdentity();
6180         try {
6181             synchronized (this) {
6182                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6183                 mWindowManager.keyguardWaitingForActivityDrawn();
6184                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6185                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6186                     updateSleepIfNeededLocked();
6187                 }
6188             }
6189         } finally {
6190             Binder.restoreCallingIdentity(token);
6191         }
6192     }
6193
6194     final void finishBooting() {
6195         synchronized (this) {
6196             if (!mBootAnimationComplete) {
6197                 mCallFinishBooting = true;
6198                 return;
6199             }
6200             mCallFinishBooting = false;
6201         }
6202
6203         ArraySet<String> completedIsas = new ArraySet<String>();
6204         for (String abi : Build.SUPPORTED_ABIS) {
6205             Process.establishZygoteConnectionForAbi(abi);
6206             final String instructionSet = VMRuntime.getInstructionSet(abi);
6207             if (!completedIsas.contains(instructionSet)) {
6208                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6209                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6210                 }
6211                 completedIsas.add(instructionSet);
6212             }
6213         }
6214
6215         IntentFilter pkgFilter = new IntentFilter();
6216         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6217         pkgFilter.addDataScheme("package");
6218         mContext.registerReceiver(new BroadcastReceiver() {
6219             @Override
6220             public void onReceive(Context context, Intent intent) {
6221                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6222                 if (pkgs != null) {
6223                     for (String pkg : pkgs) {
6224                         synchronized (ActivityManagerService.this) {
6225                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6226                                     0, "finished booting")) {
6227                                 setResultCode(Activity.RESULT_OK);
6228                                 return;
6229                             }
6230                         }
6231                     }
6232                 }
6233             }
6234         }, pkgFilter);
6235
6236         // Let system services know.
6237         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6238
6239         synchronized (this) {
6240             // Ensure that any processes we had put on hold are now started
6241             // up.
6242             final int NP = mProcessesOnHold.size();
6243             if (NP > 0) {
6244                 ArrayList<ProcessRecord> procs =
6245                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6246                 for (int ip=0; ip<NP; ip++) {
6247                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6248                             + procs.get(ip));
6249                     startProcessLocked(procs.get(ip), "on-hold", null);
6250                 }
6251             }
6252
6253             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6254                 // Start looking for apps that are abusing wake locks.
6255                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6256                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6257                 // Tell anyone interested that we are done booting!
6258                 SystemProperties.set("sys.boot_completed", "1");
6259
6260                 // And trigger dev.bootcomplete if we are not showing encryption progress
6261                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6262                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6263                     SystemProperties.set("dev.bootcomplete", "1");
6264                 }
6265                 for (int i=0; i<mStartedUsers.size(); i++) {
6266                     UserStartedState uss = mStartedUsers.valueAt(i);
6267                     if (uss.mState == UserStartedState.STATE_BOOTING) {
6268                         uss.mState = UserStartedState.STATE_RUNNING;
6269                         final int userId = mStartedUsers.keyAt(i);
6270                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6271                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6272                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6273                         broadcastIntentLocked(null, null, intent, null,
6274                                 new IIntentReceiver.Stub() {
6275                                     @Override
6276                                     public void performReceive(Intent intent, int resultCode,
6277                                             String data, Bundle extras, boolean ordered,
6278                                             boolean sticky, int sendingUser) {
6279                                         synchronized (ActivityManagerService.this) {
6280                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6281                                                     true, false);
6282                                         }
6283                                     }
6284                                 },
6285                                 0, null, null,
6286                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6287                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6288                                 userId);
6289                     }
6290                 }
6291                 scheduleStartProfilesLocked();
6292             }
6293         }
6294     }
6295
6296     @Override
6297     public void bootAnimationComplete() {
6298         final boolean callFinishBooting;
6299         synchronized (this) {
6300             callFinishBooting = mCallFinishBooting;
6301             mBootAnimationComplete = true;
6302         }
6303         if (callFinishBooting) {
6304             finishBooting();
6305         }
6306     }
6307
6308     @Override
6309     public void systemBackupRestored() {
6310         synchronized (this) {
6311             if (mSystemReady) {
6312                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
6313             } else {
6314                 Slog.w(TAG, "System backup restored before system is ready");
6315             }
6316         }
6317     }
6318
6319     final void ensureBootCompleted() {
6320         boolean booting;
6321         boolean enableScreen;
6322         synchronized (this) {
6323             booting = mBooting;
6324             mBooting = false;
6325             enableScreen = !mBooted;
6326             mBooted = true;
6327         }
6328
6329         if (booting) {
6330             finishBooting();
6331         }
6332
6333         if (enableScreen) {
6334             enableScreenAfterBoot();
6335         }
6336     }
6337
6338     @Override
6339     public final void activityResumed(IBinder token) {
6340         final long origId = Binder.clearCallingIdentity();
6341         synchronized(this) {
6342             ActivityStack stack = ActivityRecord.getStackLocked(token);
6343             if (stack != null) {
6344                 ActivityRecord.activityResumedLocked(token);
6345             }
6346         }
6347         Binder.restoreCallingIdentity(origId);
6348     }
6349
6350     @Override
6351     public final void activityPaused(IBinder token) {
6352         final long origId = Binder.clearCallingIdentity();
6353         synchronized(this) {
6354             ActivityStack stack = ActivityRecord.getStackLocked(token);
6355             if (stack != null) {
6356                 stack.activityPausedLocked(token, false);
6357             }
6358         }
6359         Binder.restoreCallingIdentity(origId);
6360     }
6361
6362     @Override
6363     public final void activityStopped(IBinder token, Bundle icicle,
6364             PersistableBundle persistentState, CharSequence description) {
6365         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6366
6367         // Refuse possible leaked file descriptors
6368         if (icicle != null && icicle.hasFileDescriptors()) {
6369             throw new IllegalArgumentException("File descriptors passed in Bundle");
6370         }
6371
6372         final long origId = Binder.clearCallingIdentity();
6373
6374         synchronized (this) {
6375             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6376             if (r != null) {
6377                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6378             }
6379         }
6380
6381         trimApplications();
6382
6383         Binder.restoreCallingIdentity(origId);
6384     }
6385
6386     @Override
6387     public final void activityDestroyed(IBinder token) {
6388         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6389         synchronized (this) {
6390             ActivityStack stack = ActivityRecord.getStackLocked(token);
6391             if (stack != null) {
6392                 stack.activityDestroyedLocked(token, "activityDestroyed");
6393             }
6394         }
6395     }
6396
6397     @Override
6398     public final void backgroundResourcesReleased(IBinder token) {
6399         final long origId = Binder.clearCallingIdentity();
6400         try {
6401             synchronized (this) {
6402                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6403                 if (stack != null) {
6404                     stack.backgroundResourcesReleased();
6405                 }
6406             }
6407         } finally {
6408             Binder.restoreCallingIdentity(origId);
6409         }
6410     }
6411
6412     @Override
6413     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6414         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6415     }
6416
6417     @Override
6418     public final void notifyEnterAnimationComplete(IBinder token) {
6419         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6420     }
6421
6422     @Override
6423     public String getCallingPackage(IBinder token) {
6424         synchronized (this) {
6425             ActivityRecord r = getCallingRecordLocked(token);
6426             return r != null ? r.info.packageName : null;
6427         }
6428     }
6429
6430     @Override
6431     public ComponentName getCallingActivity(IBinder token) {
6432         synchronized (this) {
6433             ActivityRecord r = getCallingRecordLocked(token);
6434             return r != null ? r.intent.getComponent() : null;
6435         }
6436     }
6437
6438     private ActivityRecord getCallingRecordLocked(IBinder token) {
6439         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6440         if (r == null) {
6441             return null;
6442         }
6443         return r.resultTo;
6444     }
6445
6446     @Override
6447     public ComponentName getActivityClassForToken(IBinder token) {
6448         synchronized(this) {
6449             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6450             if (r == null) {
6451                 return null;
6452             }
6453             return r.intent.getComponent();
6454         }
6455     }
6456
6457     @Override
6458     public String getPackageForToken(IBinder token) {
6459         synchronized(this) {
6460             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6461             if (r == null) {
6462                 return null;
6463             }
6464             return r.packageName;
6465         }
6466     }
6467
6468     @Override
6469     public IIntentSender getIntentSender(int type,
6470             String packageName, IBinder token, String resultWho,
6471             int requestCode, Intent[] intents, String[] resolvedTypes,
6472             int flags, Bundle options, int userId) {
6473         enforceNotIsolatedCaller("getIntentSender");
6474         // Refuse possible leaked file descriptors
6475         if (intents != null) {
6476             if (intents.length < 1) {
6477                 throw new IllegalArgumentException("Intents array length must be >= 1");
6478             }
6479             for (int i=0; i<intents.length; i++) {
6480                 Intent intent = intents[i];
6481                 if (intent != null) {
6482                     if (intent.hasFileDescriptors()) {
6483                         throw new IllegalArgumentException("File descriptors passed in Intent");
6484                     }
6485                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6486                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6487                         throw new IllegalArgumentException(
6488                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6489                     }
6490                     intents[i] = new Intent(intent);
6491                 }
6492             }
6493             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6494                 throw new IllegalArgumentException(
6495                         "Intent array length does not match resolvedTypes length");
6496             }
6497         }
6498         if (options != null) {
6499             if (options.hasFileDescriptors()) {
6500                 throw new IllegalArgumentException("File descriptors passed in options");
6501             }
6502         }
6503
6504         synchronized(this) {
6505             int callingUid = Binder.getCallingUid();
6506             int origUserId = userId;
6507             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6508                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6509                     ALLOW_NON_FULL, "getIntentSender", null);
6510             if (origUserId == UserHandle.USER_CURRENT) {
6511                 // We don't want to evaluate this until the pending intent is
6512                 // actually executed.  However, we do want to always do the
6513                 // security checking for it above.
6514                 userId = UserHandle.USER_CURRENT;
6515             }
6516             try {
6517                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6518                     int uid = AppGlobals.getPackageManager()
6519                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6520                     if (!UserHandle.isSameApp(callingUid, uid)) {
6521                         String msg = "Permission Denial: getIntentSender() from pid="
6522                             + Binder.getCallingPid()
6523                             + ", uid=" + Binder.getCallingUid()
6524                             + ", (need uid=" + uid + ")"
6525                             + " is not allowed to send as package " + packageName;
6526                         Slog.w(TAG, msg);
6527                         throw new SecurityException(msg);
6528                     }
6529                 }
6530
6531                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6532                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6533
6534             } catch (RemoteException e) {
6535                 throw new SecurityException(e);
6536             }
6537         }
6538     }
6539
6540     IIntentSender getIntentSenderLocked(int type, String packageName,
6541             int callingUid, int userId, IBinder token, String resultWho,
6542             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6543             Bundle options) {
6544         if (DEBUG_MU)
6545             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6546         ActivityRecord activity = null;
6547         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6548             activity = ActivityRecord.isInStackLocked(token);
6549             if (activity == null) {
6550                 return null;
6551             }
6552             if (activity.finishing) {
6553                 return null;
6554             }
6555         }
6556
6557         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6558         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6559         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6560         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6561                 |PendingIntent.FLAG_UPDATE_CURRENT);
6562
6563         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6564                 type, packageName, activity, resultWho,
6565                 requestCode, intents, resolvedTypes, flags, options, userId);
6566         WeakReference<PendingIntentRecord> ref;
6567         ref = mIntentSenderRecords.get(key);
6568         PendingIntentRecord rec = ref != null ? ref.get() : null;
6569         if (rec != null) {
6570             if (!cancelCurrent) {
6571                 if (updateCurrent) {
6572                     if (rec.key.requestIntent != null) {
6573                         rec.key.requestIntent.replaceExtras(intents != null ?
6574                                 intents[intents.length - 1] : null);
6575                     }
6576                     if (intents != null) {
6577                         intents[intents.length-1] = rec.key.requestIntent;
6578                         rec.key.allIntents = intents;
6579                         rec.key.allResolvedTypes = resolvedTypes;
6580                     } else {
6581                         rec.key.allIntents = null;
6582                         rec.key.allResolvedTypes = null;
6583                     }
6584                 }
6585                 return rec;
6586             }
6587             rec.canceled = true;
6588             mIntentSenderRecords.remove(key);
6589         }
6590         if (noCreate) {
6591             return rec;
6592         }
6593         rec = new PendingIntentRecord(this, key, callingUid);
6594         mIntentSenderRecords.put(key, rec.ref);
6595         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6596             if (activity.pendingResults == null) {
6597                 activity.pendingResults
6598                         = new HashSet<WeakReference<PendingIntentRecord>>();
6599             }
6600             activity.pendingResults.add(rec.ref);
6601         }
6602         return rec;
6603     }
6604
6605     @Override
6606     public void cancelIntentSender(IIntentSender sender) {
6607         if (!(sender instanceof PendingIntentRecord)) {
6608             return;
6609         }
6610         synchronized(this) {
6611             PendingIntentRecord rec = (PendingIntentRecord)sender;
6612             try {
6613                 int uid = AppGlobals.getPackageManager()
6614                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6615                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6616                     String msg = "Permission Denial: cancelIntentSender() from pid="
6617                         + Binder.getCallingPid()
6618                         + ", uid=" + Binder.getCallingUid()
6619                         + " is not allowed to cancel packges "
6620                         + rec.key.packageName;
6621                     Slog.w(TAG, msg);
6622                     throw new SecurityException(msg);
6623                 }
6624             } catch (RemoteException e) {
6625                 throw new SecurityException(e);
6626             }
6627             cancelIntentSenderLocked(rec, true);
6628         }
6629     }
6630
6631     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6632         rec.canceled = true;
6633         mIntentSenderRecords.remove(rec.key);
6634         if (cleanActivity && rec.key.activity != null) {
6635             rec.key.activity.pendingResults.remove(rec.ref);
6636         }
6637     }
6638
6639     @Override
6640     public String getPackageForIntentSender(IIntentSender pendingResult) {
6641         if (!(pendingResult instanceof PendingIntentRecord)) {
6642             return null;
6643         }
6644         try {
6645             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646             return res.key.packageName;
6647         } catch (ClassCastException e) {
6648         }
6649         return null;
6650     }
6651
6652     @Override
6653     public int getUidForIntentSender(IIntentSender sender) {
6654         if (sender instanceof PendingIntentRecord) {
6655             try {
6656                 PendingIntentRecord res = (PendingIntentRecord)sender;
6657                 return res.uid;
6658             } catch (ClassCastException e) {
6659             }
6660         }
6661         return -1;
6662     }
6663
6664     @Override
6665     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6666         if (!(pendingResult instanceof PendingIntentRecord)) {
6667             return false;
6668         }
6669         try {
6670             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6671             if (res.key.allIntents == null) {
6672                 return false;
6673             }
6674             for (int i=0; i<res.key.allIntents.length; i++) {
6675                 Intent intent = res.key.allIntents[i];
6676                 if (intent.getPackage() != null && intent.getComponent() != null) {
6677                     return false;
6678                 }
6679             }
6680             return true;
6681         } catch (ClassCastException e) {
6682         }
6683         return false;
6684     }
6685
6686     @Override
6687     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6688         if (!(pendingResult instanceof PendingIntentRecord)) {
6689             return false;
6690         }
6691         try {
6692             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6693             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6694                 return true;
6695             }
6696             return false;
6697         } catch (ClassCastException e) {
6698         }
6699         return false;
6700     }
6701
6702     @Override
6703     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6704         if (!(pendingResult instanceof PendingIntentRecord)) {
6705             return null;
6706         }
6707         try {
6708             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6709             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6710         } catch (ClassCastException e) {
6711         }
6712         return null;
6713     }
6714
6715     @Override
6716     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6717         if (!(pendingResult instanceof PendingIntentRecord)) {
6718             return null;
6719         }
6720         try {
6721             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6722             Intent intent = res.key.requestIntent;
6723             if (intent != null) {
6724                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6725                         || res.lastTagPrefix.equals(prefix))) {
6726                     return res.lastTag;
6727                 }
6728                 res.lastTagPrefix = prefix;
6729                 StringBuilder sb = new StringBuilder(128);
6730                 if (prefix != null) {
6731                     sb.append(prefix);
6732                 }
6733                 if (intent.getAction() != null) {
6734                     sb.append(intent.getAction());
6735                 } else if (intent.getComponent() != null) {
6736                     intent.getComponent().appendShortString(sb);
6737                 } else {
6738                     sb.append("?");
6739                 }
6740                 return res.lastTag = sb.toString();
6741             }
6742         } catch (ClassCastException e) {
6743         }
6744         return null;
6745     }
6746
6747     @Override
6748     public void setProcessLimit(int max) {
6749         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6750                 "setProcessLimit()");
6751         synchronized (this) {
6752             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6753             mProcessLimitOverride = max;
6754         }
6755         trimApplications();
6756     }
6757
6758     @Override
6759     public int getProcessLimit() {
6760         synchronized (this) {
6761             return mProcessLimitOverride;
6762         }
6763     }
6764
6765     void foregroundTokenDied(ForegroundToken token) {
6766         synchronized (ActivityManagerService.this) {
6767             synchronized (mPidsSelfLocked) {
6768                 ForegroundToken cur
6769                     = mForegroundProcesses.get(token.pid);
6770                 if (cur != token) {
6771                     return;
6772                 }
6773                 mForegroundProcesses.remove(token.pid);
6774                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6775                 if (pr == null) {
6776                     return;
6777                 }
6778                 pr.forcingToForeground = null;
6779                 updateProcessForegroundLocked(pr, false, false);
6780             }
6781             updateOomAdjLocked();
6782         }
6783     }
6784
6785     @Override
6786     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6787         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6788                 "setProcessForeground()");
6789         synchronized(this) {
6790             boolean changed = false;
6791             
6792             synchronized (mPidsSelfLocked) {
6793                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6794                 if (pr == null && isForeground) {
6795                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6796                     return;
6797                 }
6798                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6799                 if (oldToken != null) {
6800                     oldToken.token.unlinkToDeath(oldToken, 0);
6801                     mForegroundProcesses.remove(pid);
6802                     if (pr != null) {
6803                         pr.forcingToForeground = null;
6804                     }
6805                     changed = true;
6806                 }
6807                 if (isForeground && token != null) {
6808                     ForegroundToken newToken = new ForegroundToken() {
6809                         @Override
6810                         public void binderDied() {
6811                             foregroundTokenDied(this);
6812                         }
6813                     };
6814                     newToken.pid = pid;
6815                     newToken.token = token;
6816                     try {
6817                         token.linkToDeath(newToken, 0);
6818                         mForegroundProcesses.put(pid, newToken);
6819                         pr.forcingToForeground = token;
6820                         changed = true;
6821                     } catch (RemoteException e) {
6822                         // If the process died while doing this, we will later
6823                         // do the cleanup with the process death link.
6824                     }
6825                 }
6826             }
6827             
6828             if (changed) {
6829                 updateOomAdjLocked();
6830             }
6831         }
6832     }
6833
6834     // =========================================================
6835     // PROCESS INFO
6836     // =========================================================
6837
6838     static class ProcessInfoService extends IProcessInfoService.Stub {
6839         final ActivityManagerService mActivityManagerService;
6840         ProcessInfoService(ActivityManagerService activityManagerService) {
6841             mActivityManagerService = activityManagerService;
6842         }
6843
6844         @Override
6845         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6846             mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6847         }
6848     }
6849
6850     /**
6851      * For each PID in the given input array, write the current process state
6852      * for that process into the output array, or -1 to indicate that no
6853      * process with the given PID exists.
6854      */
6855     public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6856         if (pids == null) {
6857             throw new NullPointerException("pids");
6858         } else if (states == null) {
6859             throw new NullPointerException("states");
6860         } else if (pids.length != states.length) {
6861             throw new IllegalArgumentException("input and output arrays have different lengths!");
6862         }
6863
6864         synchronized (mPidsSelfLocked) {
6865             for (int i = 0; i < pids.length; i++) {
6866                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6867                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6868                         pr.curProcState;
6869             }
6870         }
6871     }
6872
6873     // =========================================================
6874     // PERMISSIONS
6875     // =========================================================
6876
6877     static class PermissionController extends IPermissionController.Stub {
6878         ActivityManagerService mActivityManagerService;
6879         PermissionController(ActivityManagerService activityManagerService) {
6880             mActivityManagerService = activityManagerService;
6881         }
6882
6883         @Override
6884         public boolean checkPermission(String permission, int pid, int uid) {
6885             return mActivityManagerService.checkPermission(permission, pid,
6886                     uid) == PackageManager.PERMISSION_GRANTED;
6887         }
6888     }
6889
6890     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6891         @Override
6892         public int checkComponentPermission(String permission, int pid, int uid,
6893                 int owningUid, boolean exported) {
6894             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6895                     owningUid, exported);
6896         }
6897
6898         @Override
6899         public Object getAMSLock() {
6900             return ActivityManagerService.this;
6901         }
6902     }
6903
6904     /**
6905      * This can be called with or without the global lock held.
6906      */
6907     int checkComponentPermission(String permission, int pid, int uid,
6908             int owningUid, boolean exported) {
6909         if (pid == MY_PID) {
6910             return PackageManager.PERMISSION_GRANTED;
6911         }
6912         return ActivityManager.checkComponentPermission(permission, uid,
6913                 owningUid, exported);
6914     }
6915
6916     /**
6917      * As the only public entry point for permissions checking, this method
6918      * can enforce the semantic that requesting a check on a null global
6919      * permission is automatically denied.  (Internally a null permission
6920      * string is used when calling {@link #checkComponentPermission} in cases
6921      * when only uid-based security is needed.)
6922      * 
6923      * This can be called with or without the global lock held.
6924      */
6925     @Override
6926     public int checkPermission(String permission, int pid, int uid) {
6927         if (permission == null) {
6928             return PackageManager.PERMISSION_DENIED;
6929         }
6930         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6931     }
6932
6933     @Override
6934     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6935         if (permission == null) {
6936             return PackageManager.PERMISSION_DENIED;
6937         }
6938
6939         // We might be performing an operation on behalf of an indirect binder
6940         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6941         // client identity accordingly before proceeding.
6942         Identity tlsIdentity = sCallerIdentity.get();
6943         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6944             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6945                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6946             uid = tlsIdentity.uid;
6947             pid = tlsIdentity.pid;
6948         }
6949
6950         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6951     }
6952
6953     /**
6954      * Binder IPC calls go through the public entry point.
6955      * This can be called with or without the global lock held.
6956      */
6957     int checkCallingPermission(String permission) {
6958         return checkPermission(permission,
6959                 Binder.getCallingPid(),
6960                 UserHandle.getAppId(Binder.getCallingUid()));
6961     }
6962
6963     /**
6964      * This can be called with or without the global lock held.
6965      */
6966     void enforceCallingPermission(String permission, String func) {
6967         if (checkCallingPermission(permission)
6968                 == PackageManager.PERMISSION_GRANTED) {
6969             return;
6970         }
6971
6972         String msg = "Permission Denial: " + func + " from pid="
6973                 + Binder.getCallingPid()
6974                 + ", uid=" + Binder.getCallingUid()
6975                 + " requires " + permission;
6976         Slog.w(TAG, msg);
6977         throw new SecurityException(msg);
6978     }
6979
6980     /**
6981      * Determine if UID is holding permissions required to access {@link Uri} in
6982      * the given {@link ProviderInfo}. Final permission checking is always done
6983      * in {@link ContentProvider}.
6984      */
6985     private final boolean checkHoldingPermissionsLocked(
6986             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6987         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6988                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6989         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6990             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6991                     != PERMISSION_GRANTED) {
6992                 return false;
6993             }
6994         }
6995         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6996     }
6997
6998     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6999             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7000         if (pi.applicationInfo.uid == uid) {
7001             return true;
7002         } else if (!pi.exported) {
7003             return false;
7004         }
7005
7006         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7007         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7008         try {
7009             // check if target holds top-level <provider> permissions
7010             if (!readMet && pi.readPermission != null && considerUidPermissions
7011                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7012                 readMet = true;
7013             }
7014             if (!writeMet && pi.writePermission != null && considerUidPermissions
7015                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7016                 writeMet = true;
7017             }
7018
7019             // track if unprotected read/write is allowed; any denied
7020             // <path-permission> below removes this ability
7021             boolean allowDefaultRead = pi.readPermission == null;
7022             boolean allowDefaultWrite = pi.writePermission == null;
7023
7024             // check if target holds any <path-permission> that match uri
7025             final PathPermission[] pps = pi.pathPermissions;
7026             if (pps != null) {
7027                 final String path = grantUri.uri.getPath();
7028                 int i = pps.length;
7029                 while (i > 0 && (!readMet || !writeMet)) {
7030                     i--;
7031                     PathPermission pp = pps[i];
7032                     if (pp.match(path)) {
7033                         if (!readMet) {
7034                             final String pprperm = pp.getReadPermission();
7035                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7036                                     + pprperm + " for " + pp.getPath()
7037                                     + ": match=" + pp.match(path)
7038                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7039                             if (pprperm != null) {
7040                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7041                                         == PERMISSION_GRANTED) {
7042                                     readMet = true;
7043                                 } else {
7044                                     allowDefaultRead = false;
7045                                 }
7046                             }
7047                         }
7048                         if (!writeMet) {
7049                             final String ppwperm = pp.getWritePermission();
7050                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7051                                     + ppwperm + " for " + pp.getPath()
7052                                     + ": match=" + pp.match(path)
7053                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7054                             if (ppwperm != null) {
7055                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7056                                         == PERMISSION_GRANTED) {
7057                                     writeMet = true;
7058                                 } else {
7059                                     allowDefaultWrite = false;
7060                                 }
7061                             }
7062                         }
7063                     }
7064                 }
7065             }
7066
7067             // grant unprotected <provider> read/write, if not blocked by
7068             // <path-permission> above
7069             if (allowDefaultRead) readMet = true;
7070             if (allowDefaultWrite) writeMet = true;
7071
7072         } catch (RemoteException e) {
7073             return false;
7074         }
7075
7076         return readMet && writeMet;
7077     }
7078
7079     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7080         ProviderInfo pi = null;
7081         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7082         if (cpr != null) {
7083             pi = cpr.info;
7084         } else {
7085             try {
7086                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7087                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7088             } catch (RemoteException ex) {
7089             }
7090         }
7091         return pi;
7092     }
7093
7094     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7095         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7096         if (targetUris != null) {
7097             return targetUris.get(grantUri);
7098         }
7099         return null;
7100     }
7101
7102     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7103             String targetPkg, int targetUid, GrantUri grantUri) {
7104         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7105         if (targetUris == null) {
7106             targetUris = Maps.newArrayMap();
7107             mGrantedUriPermissions.put(targetUid, targetUris);
7108         }
7109
7110         UriPermission perm = targetUris.get(grantUri);
7111         if (perm == null) {
7112             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7113             targetUris.put(grantUri, perm);
7114         }
7115
7116         return perm;
7117     }
7118
7119     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7120             final int modeFlags) {
7121         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7122         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7123                 : UriPermission.STRENGTH_OWNED;
7124
7125         // Root gets to do everything.
7126         if (uid == 0) {
7127             return true;
7128         }
7129
7130         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7131         if (perms == null) return false;
7132
7133         // First look for exact match
7134         final UriPermission exactPerm = perms.get(grantUri);
7135         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7136             return true;
7137         }
7138
7139         // No exact match, look for prefixes
7140         final int N = perms.size();
7141         for (int i = 0; i < N; i++) {
7142             final UriPermission perm = perms.valueAt(i);
7143             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7144                     && perm.getStrength(modeFlags) >= minStrength) {
7145                 return true;
7146             }
7147         }
7148
7149         return false;
7150     }
7151
7152     /**
7153      * @param uri This uri must NOT contain an embedded userId.
7154      * @param userId The userId in which the uri is to be resolved.
7155      */
7156     @Override
7157     public int checkUriPermission(Uri uri, int pid, int uid,
7158             final int modeFlags, int userId, IBinder callerToken) {
7159         enforceNotIsolatedCaller("checkUriPermission");
7160
7161         // Another redirected-binder-call permissions check as in
7162         // {@link checkPermissionWithToken}.
7163         Identity tlsIdentity = sCallerIdentity.get();
7164         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7165             uid = tlsIdentity.uid;
7166             pid = tlsIdentity.pid;
7167         }
7168
7169         // Our own process gets to do everything.
7170         if (pid == MY_PID) {
7171             return PackageManager.PERMISSION_GRANTED;
7172         }
7173         synchronized (this) {
7174             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7175                     ? PackageManager.PERMISSION_GRANTED
7176                     : PackageManager.PERMISSION_DENIED;
7177         }
7178     }
7179
7180     /**
7181      * Check if the targetPkg can be granted permission to access uri by
7182      * the callingUid using the given modeFlags.  Throws a security exception
7183      * if callingUid is not allowed to do this.  Returns the uid of the target
7184      * if the URI permission grant should be performed; returns -1 if it is not
7185      * needed (for example targetPkg already has permission to access the URI).
7186      * If you already know the uid of the target, you can supply it in
7187      * lastTargetUid else set that to -1.
7188      */
7189     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7190             final int modeFlags, int lastTargetUid) {
7191         if (!Intent.isAccessUriMode(modeFlags)) {
7192             return -1;
7193         }
7194
7195         if (targetPkg != null) {
7196             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7197                     "Checking grant " + targetPkg + " permission to " + grantUri);
7198         }
7199         
7200         final IPackageManager pm = AppGlobals.getPackageManager();
7201
7202         // If this is not a content: uri, we can't do anything with it.
7203         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7204             if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7205                     "Can't grant URI permission for non-content URI: " + grantUri);
7206             return -1;
7207         }
7208
7209         final String authority = grantUri.uri.getAuthority();
7210         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7211         if (pi == null) {
7212             Slog.w(TAG, "No content provider found for permission check: " +
7213                     grantUri.uri.toSafeString());
7214             return -1;
7215         }
7216
7217         int targetUid = lastTargetUid;
7218         if (targetUid < 0 && targetPkg != null) {
7219             try {
7220                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7221                 if (targetUid < 0) {
7222                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7223                             "Can't grant URI permission no uid for: " + targetPkg);
7224                     return -1;
7225                 }
7226             } catch (RemoteException ex) {
7227                 return -1;
7228             }
7229         }
7230
7231         if (targetUid >= 0) {
7232             // First...  does the target actually need this permission?
7233             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7234                 // No need to grant the target this permission.
7235                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7236                         "Target " + targetPkg + " already has full permission to " + grantUri);
7237                 return -1;
7238             }
7239         } else {
7240             // First...  there is no target package, so can anyone access it?
7241             boolean allowed = pi.exported;
7242             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7243                 if (pi.readPermission != null) {
7244                     allowed = false;
7245                 }
7246             }
7247             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7248                 if (pi.writePermission != null) {
7249                     allowed = false;
7250                 }
7251             }
7252             if (allowed) {
7253                 return -1;
7254             }
7255         }
7256
7257         /* There is a special cross user grant if:
7258          * - The target is on another user.
7259          * - Apps on the current user can access the uri without any uid permissions.
7260          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7261          * grant uri permissions.
7262          */
7263         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7264                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7265                 modeFlags, false /*without considering the uid permissions*/);
7266
7267         // Second...  is the provider allowing granting of URI permissions?
7268         if (!specialCrossUserGrant) {
7269             if (!pi.grantUriPermissions) {
7270                 throw new SecurityException("Provider " + pi.packageName
7271                         + "/" + pi.name
7272                         + " does not allow granting of Uri permissions (uri "
7273                         + grantUri + ")");
7274             }
7275             if (pi.uriPermissionPatterns != null) {
7276                 final int N = pi.uriPermissionPatterns.length;
7277                 boolean allowed = false;
7278                 for (int i=0; i<N; i++) {
7279                     if (pi.uriPermissionPatterns[i] != null
7280                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7281                         allowed = true;
7282                         break;
7283                     }
7284                 }
7285                 if (!allowed) {
7286                     throw new SecurityException("Provider " + pi.packageName
7287                             + "/" + pi.name
7288                             + " does not allow granting of permission to path of Uri "
7289                             + grantUri);
7290                 }
7291             }
7292         }
7293
7294         // Third...  does the caller itself have permission to access
7295         // this uri?
7296         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7297             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7298                 // Require they hold a strong enough Uri permission
7299                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7300                     throw new SecurityException("Uid " + callingUid
7301                             + " does not have permission to uri " + grantUri);
7302                 }
7303             }
7304         }
7305         return targetUid;
7306     }
7307
7308     /**
7309      * @param uri This uri must NOT contain an embedded userId.
7310      * @param userId The userId in which the uri is to be resolved.
7311      */
7312     @Override
7313     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7314             final int modeFlags, int userId) {
7315         enforceNotIsolatedCaller("checkGrantUriPermission");
7316         synchronized(this) {
7317             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7318                     new GrantUri(userId, uri, false), modeFlags, -1);
7319         }
7320     }
7321
7322     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7323             final int modeFlags, UriPermissionOwner owner) {
7324         if (!Intent.isAccessUriMode(modeFlags)) {
7325             return;
7326         }
7327
7328         // So here we are: the caller has the assumed permission
7329         // to the uri, and the target doesn't.  Let's now give this to
7330         // the target.
7331
7332         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7333                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7334
7335         final String authority = grantUri.uri.getAuthority();
7336         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7337         if (pi == null) {
7338             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7339             return;
7340         }
7341
7342         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7343             grantUri.prefix = true;
7344         }
7345         final UriPermission perm = findOrCreateUriPermissionLocked(
7346                 pi.packageName, targetPkg, targetUid, grantUri);
7347         perm.grantModes(modeFlags, owner);
7348     }
7349
7350     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7351             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7352         if (targetPkg == null) {
7353             throw new NullPointerException("targetPkg");
7354         }
7355         int targetUid;
7356         final IPackageManager pm = AppGlobals.getPackageManager();
7357         try {
7358             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7359         } catch (RemoteException ex) {
7360             return;
7361         }
7362
7363         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7364                 targetUid);
7365         if (targetUid < 0) {
7366             return;
7367         }
7368
7369         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7370                 owner);
7371     }
7372
7373     static class NeededUriGrants extends ArrayList<GrantUri> {
7374         final String targetPkg;
7375         final int targetUid;
7376         final int flags;
7377
7378         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7379             this.targetPkg = targetPkg;
7380             this.targetUid = targetUid;
7381             this.flags = flags;
7382         }
7383     }
7384
7385     /**
7386      * Like checkGrantUriPermissionLocked, but takes an Intent.
7387      */
7388     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7389             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7390         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7391                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7392                 + " clip=" + (intent != null ? intent.getClipData() : null)
7393                 + " from " + intent + "; flags=0x"
7394                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7395
7396         if (targetPkg == null) {
7397             throw new NullPointerException("targetPkg");
7398         }
7399
7400         if (intent == null) {
7401             return null;
7402         }
7403         Uri data = intent.getData();
7404         ClipData clip = intent.getClipData();
7405         if (data == null && clip == null) {
7406             return null;
7407         }
7408         // Default userId for uris in the intent (if they don't specify it themselves)
7409         int contentUserHint = intent.getContentUserHint();
7410         if (contentUserHint == UserHandle.USER_CURRENT) {
7411             contentUserHint = UserHandle.getUserId(callingUid);
7412         }
7413         final IPackageManager pm = AppGlobals.getPackageManager();
7414         int targetUid;
7415         if (needed != null) {
7416             targetUid = needed.targetUid;
7417         } else {
7418             try {
7419                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7420             } catch (RemoteException ex) {
7421                 return null;
7422             }
7423             if (targetUid < 0) {
7424                 if (DEBUG_URI_PERMISSION) {
7425                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7426                             + " on user " + targetUserId);
7427                 }
7428                 return null;
7429             }
7430         }
7431         if (data != null) {
7432             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7433             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7434                     targetUid);
7435             if (targetUid > 0) {
7436                 if (needed == null) {
7437                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7438                 }
7439                 needed.add(grantUri);
7440             }
7441         }
7442         if (clip != null) {
7443             for (int i=0; i<clip.getItemCount(); i++) {
7444                 Uri uri = clip.getItemAt(i).getUri();
7445                 if (uri != null) {
7446                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7447                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7448                             targetUid);
7449                     if (targetUid > 0) {
7450                         if (needed == null) {
7451                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7452                         }
7453                         needed.add(grantUri);
7454                     }
7455                 } else {
7456                     Intent clipIntent = clip.getItemAt(i).getIntent();
7457                     if (clipIntent != null) {
7458                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7459                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7460                         if (newNeeded != null) {
7461                             needed = newNeeded;
7462                         }
7463                     }
7464                 }
7465             }
7466         }
7467
7468         return needed;
7469     }
7470
7471     /**
7472      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7473      */
7474     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7475             UriPermissionOwner owner) {
7476         if (needed != null) {
7477             for (int i=0; i<needed.size(); i++) {
7478                 GrantUri grantUri = needed.get(i);
7479                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7480                         grantUri, needed.flags, owner);
7481             }
7482         }
7483     }
7484
7485     void grantUriPermissionFromIntentLocked(int callingUid,
7486             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7487         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7488                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7489         if (needed == null) {
7490             return;
7491         }
7492
7493         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7494     }
7495
7496     /**
7497      * @param uri This uri must NOT contain an embedded userId.
7498      * @param userId The userId in which the uri is to be resolved.
7499      */
7500     @Override
7501     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7502             final int modeFlags, int userId) {
7503         enforceNotIsolatedCaller("grantUriPermission");
7504         GrantUri grantUri = new GrantUri(userId, uri, false);
7505         synchronized(this) {
7506             final ProcessRecord r = getRecordForAppLocked(caller);
7507             if (r == null) {
7508                 throw new SecurityException("Unable to find app for caller "
7509                         + caller
7510                         + " when granting permission to uri " + grantUri);
7511             }
7512             if (targetPkg == null) {
7513                 throw new IllegalArgumentException("null target");
7514             }
7515             if (grantUri == null) {
7516                 throw new IllegalArgumentException("null uri");
7517             }
7518
7519             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7520                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7521                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7522                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7523
7524             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7525                     UserHandle.getUserId(r.uid));
7526         }
7527     }
7528
7529     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7530         if (perm.modeFlags == 0) {
7531             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7532                     perm.targetUid);
7533             if (perms != null) {
7534                 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7535                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7536
7537                 perms.remove(perm.uri);
7538                 if (perms.isEmpty()) {
7539                     mGrantedUriPermissions.remove(perm.targetUid);
7540                 }
7541             }
7542         }
7543     }
7544
7545     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7546         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7547
7548         final IPackageManager pm = AppGlobals.getPackageManager();
7549         final String authority = grantUri.uri.getAuthority();
7550         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7551         if (pi == null) {
7552             Slog.w(TAG, "No content provider found for permission revoke: "
7553                     + grantUri.toSafeString());
7554             return;
7555         }
7556
7557         // Does the caller have this permission on the URI?
7558         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7559             // If they don't have direct access to the URI, then revoke any
7560             // ownerless URI permissions that have been granted to them.
7561             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7562             if (perms != null) {
7563                 boolean persistChanged = false;
7564                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7565                     final UriPermission perm = it.next();
7566                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7567                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7568                         if (DEBUG_URI_PERMISSION)
7569                             Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7570                                     " permission to " + perm.uri);
7571                         persistChanged |= perm.revokeModes(
7572                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7573                         if (perm.modeFlags == 0) {
7574                             it.remove();
7575                         }
7576                     }
7577                 }
7578                 if (perms.isEmpty()) {
7579                     mGrantedUriPermissions.remove(callingUid);
7580                 }
7581                 if (persistChanged) {
7582                     schedulePersistUriGrants();
7583                 }
7584             }
7585             return;
7586         }
7587
7588         boolean persistChanged = false;
7589
7590         // Go through all of the permissions and remove any that match.
7591         int N = mGrantedUriPermissions.size();
7592         for (int i = 0; i < N; i++) {
7593             final int targetUid = mGrantedUriPermissions.keyAt(i);
7594             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7595
7596             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7597                 final UriPermission perm = it.next();
7598                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7599                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7600                     if (DEBUG_URI_PERMISSION)
7601                         Slog.v(TAG,
7602                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7603                     persistChanged |= perm.revokeModes(
7604                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7605                     if (perm.modeFlags == 0) {
7606                         it.remove();
7607                     }
7608                 }
7609             }
7610
7611             if (perms.isEmpty()) {
7612                 mGrantedUriPermissions.remove(targetUid);
7613                 N--;
7614                 i--;
7615             }
7616         }
7617
7618         if (persistChanged) {
7619             schedulePersistUriGrants();
7620         }
7621     }
7622
7623     /**
7624      * @param uri This uri must NOT contain an embedded userId.
7625      * @param userId The userId in which the uri is to be resolved.
7626      */
7627     @Override
7628     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7629             int userId) {
7630         enforceNotIsolatedCaller("revokeUriPermission");
7631         synchronized(this) {
7632             final ProcessRecord r = getRecordForAppLocked(caller);
7633             if (r == null) {
7634                 throw new SecurityException("Unable to find app for caller "
7635                         + caller
7636                         + " when revoking permission to uri " + uri);
7637             }
7638             if (uri == null) {
7639                 Slog.w(TAG, "revokeUriPermission: null uri");
7640                 return;
7641             }
7642
7643             if (!Intent.isAccessUriMode(modeFlags)) {
7644                 return;
7645             }
7646
7647             final IPackageManager pm = AppGlobals.getPackageManager();
7648             final String authority = uri.getAuthority();
7649             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7650             if (pi == null) {
7651                 Slog.w(TAG, "No content provider found for permission revoke: "
7652                         + uri.toSafeString());
7653                 return;
7654             }
7655
7656             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7657         }
7658     }
7659
7660     /**
7661      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7662      * given package.
7663      *
7664      * @param packageName Package name to match, or {@code null} to apply to all
7665      *            packages.
7666      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7667      *            to all users.
7668      * @param persistable If persistable grants should be removed.
7669      */
7670     private void removeUriPermissionsForPackageLocked(
7671             String packageName, int userHandle, boolean persistable) {
7672         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7673             throw new IllegalArgumentException("Must narrow by either package or user");
7674         }
7675
7676         boolean persistChanged = false;
7677
7678         int N = mGrantedUriPermissions.size();
7679         for (int i = 0; i < N; i++) {
7680             final int targetUid = mGrantedUriPermissions.keyAt(i);
7681             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7682
7683             // Only inspect grants matching user
7684             if (userHandle == UserHandle.USER_ALL
7685                     || userHandle == UserHandle.getUserId(targetUid)) {
7686                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7687                     final UriPermission perm = it.next();
7688
7689                     // Only inspect grants matching package
7690                     if (packageName == null || perm.sourcePkg.equals(packageName)
7691                             || perm.targetPkg.equals(packageName)) {
7692                         persistChanged |= perm.revokeModes(persistable
7693                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7694
7695                         // Only remove when no modes remain; any persisted grants
7696                         // will keep this alive.
7697                         if (perm.modeFlags == 0) {
7698                             it.remove();
7699                         }
7700                     }
7701                 }
7702
7703                 if (perms.isEmpty()) {
7704                     mGrantedUriPermissions.remove(targetUid);
7705                     N--;
7706                     i--;
7707                 }
7708             }
7709         }
7710
7711         if (persistChanged) {
7712             schedulePersistUriGrants();
7713         }
7714     }
7715
7716     @Override
7717     public IBinder newUriPermissionOwner(String name) {
7718         enforceNotIsolatedCaller("newUriPermissionOwner");
7719         synchronized(this) {
7720             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7721             return owner.getExternalTokenLocked();
7722         }
7723     }
7724
7725     /**
7726      * @param uri This uri must NOT contain an embedded userId.
7727      * @param sourceUserId The userId in which the uri is to be resolved.
7728      * @param targetUserId The userId of the app that receives the grant.
7729      */
7730     @Override
7731     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7732             final int modeFlags, int sourceUserId, int targetUserId) {
7733         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7734                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7735         synchronized(this) {
7736             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7737             if (owner == null) {
7738                 throw new IllegalArgumentException("Unknown owner: " + token);
7739             }
7740             if (fromUid != Binder.getCallingUid()) {
7741                 if (Binder.getCallingUid() != Process.myUid()) {
7742                     // Only system code can grant URI permissions on behalf
7743                     // of other users.
7744                     throw new SecurityException("nice try");
7745                 }
7746             }
7747             if (targetPkg == null) {
7748                 throw new IllegalArgumentException("null target");
7749             }
7750             if (uri == null) {
7751                 throw new IllegalArgumentException("null uri");
7752             }
7753
7754             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7755                     modeFlags, owner, targetUserId);
7756         }
7757     }
7758
7759     /**
7760      * @param uri This uri must NOT contain an embedded userId.
7761      * @param userId The userId in which the uri is to be resolved.
7762      */
7763     @Override
7764     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7765         synchronized(this) {
7766             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7767             if (owner == null) {
7768                 throw new IllegalArgumentException("Unknown owner: " + token);
7769             }
7770
7771             if (uri == null) {
7772                 owner.removeUriPermissionsLocked(mode);
7773             } else {
7774                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7775             }
7776         }
7777     }
7778
7779     private void schedulePersistUriGrants() {
7780         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7781             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7782                     10 * DateUtils.SECOND_IN_MILLIS);
7783         }
7784     }
7785
7786     private void writeGrantedUriPermissions() {
7787         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7788
7789         // Snapshot permissions so we can persist without lock
7790         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7791         synchronized (this) {
7792             final int size = mGrantedUriPermissions.size();
7793             for (int i = 0; i < size; i++) {
7794                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7795                 for (UriPermission perm : perms.values()) {
7796                     if (perm.persistedModeFlags != 0) {
7797                         persist.add(perm.snapshot());
7798                     }
7799                 }
7800             }
7801         }
7802
7803         FileOutputStream fos = null;
7804         try {
7805             fos = mGrantFile.startWrite();
7806
7807             XmlSerializer out = new FastXmlSerializer();
7808             out.setOutput(fos, "utf-8");
7809             out.startDocument(null, true);
7810             out.startTag(null, TAG_URI_GRANTS);
7811             for (UriPermission.Snapshot perm : persist) {
7812                 out.startTag(null, TAG_URI_GRANT);
7813                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7814                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7815                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7816                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7817                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7818                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7819                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7820                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7821                 out.endTag(null, TAG_URI_GRANT);
7822             }
7823             out.endTag(null, TAG_URI_GRANTS);
7824             out.endDocument();
7825
7826             mGrantFile.finishWrite(fos);
7827         } catch (IOException e) {
7828             if (fos != null) {
7829                 mGrantFile.failWrite(fos);
7830             }
7831         }
7832     }
7833
7834     private void readGrantedUriPermissionsLocked() {
7835         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7836
7837         final long now = System.currentTimeMillis();
7838
7839         FileInputStream fis = null;
7840         try {
7841             fis = mGrantFile.openRead();
7842             final XmlPullParser in = Xml.newPullParser();
7843             in.setInput(fis, null);
7844
7845             int type;
7846             while ((type = in.next()) != END_DOCUMENT) {
7847                 final String tag = in.getName();
7848                 if (type == START_TAG) {
7849                     if (TAG_URI_GRANT.equals(tag)) {
7850                         final int sourceUserId;
7851                         final int targetUserId;
7852                         final int userHandle = readIntAttribute(in,
7853                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7854                         if (userHandle != UserHandle.USER_NULL) {
7855                             // For backwards compatibility.
7856                             sourceUserId = userHandle;
7857                             targetUserId = userHandle;
7858                         } else {
7859                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7860                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7861                         }
7862                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7863                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7864                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7865                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7866                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7867                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7868
7869                         // Sanity check that provider still belongs to source package
7870                         final ProviderInfo pi = getProviderInfoLocked(
7871                                 uri.getAuthority(), sourceUserId);
7872                         if (pi != null && sourcePkg.equals(pi.packageName)) {
7873                             int targetUid = -1;
7874                             try {
7875                                 targetUid = AppGlobals.getPackageManager()
7876                                         .getPackageUid(targetPkg, targetUserId);
7877                             } catch (RemoteException e) {
7878                             }
7879                             if (targetUid != -1) {
7880                                 final UriPermission perm = findOrCreateUriPermissionLocked(
7881                                         sourcePkg, targetPkg, targetUid,
7882                                         new GrantUri(sourceUserId, uri, prefix));
7883                                 perm.initPersistedModes(modeFlags, createdTime);
7884                             }
7885                         } else {
7886                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7887                                     + " but instead found " + pi);
7888                         }
7889                     }
7890                 }
7891             }
7892         } catch (FileNotFoundException e) {
7893             // Missing grants is okay
7894         } catch (IOException e) {
7895             Slog.wtf(TAG, "Failed reading Uri grants", e);
7896         } catch (XmlPullParserException e) {
7897             Slog.wtf(TAG, "Failed reading Uri grants", e);
7898         } finally {
7899             IoUtils.closeQuietly(fis);
7900         }
7901     }
7902
7903     /**
7904      * @param uri This uri must NOT contain an embedded userId.
7905      * @param userId The userId in which the uri is to be resolved.
7906      */
7907     @Override
7908     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7909         enforceNotIsolatedCaller("takePersistableUriPermission");
7910
7911         Preconditions.checkFlagsArgument(modeFlags,
7912                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7913
7914         synchronized (this) {
7915             final int callingUid = Binder.getCallingUid();
7916             boolean persistChanged = false;
7917             GrantUri grantUri = new GrantUri(userId, uri, false);
7918
7919             UriPermission exactPerm = findUriPermissionLocked(callingUid,
7920                     new GrantUri(userId, uri, false));
7921             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7922                     new GrantUri(userId, uri, true));
7923
7924             final boolean exactValid = (exactPerm != null)
7925                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7926             final boolean prefixValid = (prefixPerm != null)
7927                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7928
7929             if (!(exactValid || prefixValid)) {
7930                 throw new SecurityException("No persistable permission grants found for UID "
7931                         + callingUid + " and Uri " + grantUri.toSafeString());
7932             }
7933
7934             if (exactValid) {
7935                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7936             }
7937             if (prefixValid) {
7938                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7939             }
7940
7941             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7942
7943             if (persistChanged) {
7944                 schedulePersistUriGrants();
7945             }
7946         }
7947     }
7948
7949     /**
7950      * @param uri This uri must NOT contain an embedded userId.
7951      * @param userId The userId in which the uri is to be resolved.
7952      */
7953     @Override
7954     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7955         enforceNotIsolatedCaller("releasePersistableUriPermission");
7956
7957         Preconditions.checkFlagsArgument(modeFlags,
7958                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7959
7960         synchronized (this) {
7961             final int callingUid = Binder.getCallingUid();
7962             boolean persistChanged = false;
7963
7964             UriPermission exactPerm = findUriPermissionLocked(callingUid,
7965                     new GrantUri(userId, uri, false));
7966             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7967                     new GrantUri(userId, uri, true));
7968             if (exactPerm == null && prefixPerm == null) {
7969                 throw new SecurityException("No permission grants found for UID " + callingUid
7970                         + " and Uri " + uri.toSafeString());
7971             }
7972
7973             if (exactPerm != null) {
7974                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7975                 removeUriPermissionIfNeededLocked(exactPerm);
7976             }
7977             if (prefixPerm != null) {
7978                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7979                 removeUriPermissionIfNeededLocked(prefixPerm);
7980             }
7981
7982             if (persistChanged) {
7983                 schedulePersistUriGrants();
7984             }
7985         }
7986     }
7987
7988     /**
7989      * Prune any older {@link UriPermission} for the given UID until outstanding
7990      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7991      *
7992      * @return if any mutations occured that require persisting.
7993      */
7994     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7995         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7996         if (perms == null) return false;
7997         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7998
7999         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8000         for (UriPermission perm : perms.values()) {
8001             if (perm.persistedModeFlags != 0) {
8002                 persisted.add(perm);
8003             }
8004         }
8005
8006         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8007         if (trimCount <= 0) return false;
8008
8009         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8010         for (int i = 0; i < trimCount; i++) {
8011             final UriPermission perm = persisted.get(i);
8012
8013             if (DEBUG_URI_PERMISSION) {
8014                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8015             }
8016
8017             perm.releasePersistableModes(~0);
8018             removeUriPermissionIfNeededLocked(perm);
8019         }
8020
8021         return true;
8022     }
8023
8024     @Override
8025     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8026             String packageName, boolean incoming) {
8027         enforceNotIsolatedCaller("getPersistedUriPermissions");
8028         Preconditions.checkNotNull(packageName, "packageName");
8029
8030         final int callingUid = Binder.getCallingUid();
8031         final IPackageManager pm = AppGlobals.getPackageManager();
8032         try {
8033             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8034             if (packageUid != callingUid) {
8035                 throw new SecurityException(
8036                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8037             }
8038         } catch (RemoteException e) {
8039             throw new SecurityException("Failed to verify package name ownership");
8040         }
8041
8042         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8043         synchronized (this) {
8044             if (incoming) {
8045                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8046                         callingUid);
8047                 if (perms == null) {
8048                     Slog.w(TAG, "No permission grants found for " + packageName);
8049                 } else {
8050                     for (UriPermission perm : perms.values()) {
8051                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8052                             result.add(perm.buildPersistedPublicApiObject());
8053                         }
8054                     }
8055                 }
8056             } else {
8057                 final int size = mGrantedUriPermissions.size();
8058                 for (int i = 0; i < size; i++) {
8059                     final ArrayMap<GrantUri, UriPermission> perms =
8060                             mGrantedUriPermissions.valueAt(i);
8061                     for (UriPermission perm : perms.values()) {
8062                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8063                             result.add(perm.buildPersistedPublicApiObject());
8064                         }
8065                     }
8066                 }
8067             }
8068         }
8069         return new ParceledListSlice<android.content.UriPermission>(result);
8070     }
8071
8072     @Override
8073     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8074         synchronized (this) {
8075             ProcessRecord app =
8076                 who != null ? getRecordForAppLocked(who) : null;
8077             if (app == null) return;
8078
8079             Message msg = Message.obtain();
8080             msg.what = WAIT_FOR_DEBUGGER_MSG;
8081             msg.obj = app;
8082             msg.arg1 = waiting ? 1 : 0;
8083             mUiHandler.sendMessage(msg);
8084         }
8085     }
8086
8087     @Override
8088     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8089         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8090         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8091         outInfo.availMem = Process.getFreeMemory();
8092         outInfo.totalMem = Process.getTotalMemory();
8093         outInfo.threshold = homeAppMem;
8094         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8095         outInfo.hiddenAppThreshold = cachedAppMem;
8096         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8097                 ProcessList.SERVICE_ADJ);
8098         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8099                 ProcessList.VISIBLE_APP_ADJ);
8100         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8101                 ProcessList.FOREGROUND_APP_ADJ);
8102     }
8103     
8104     // =========================================================
8105     // TASK MANAGEMENT
8106     // =========================================================
8107
8108     @Override
8109     public List<IAppTask> getAppTasks(String callingPackage) {
8110         int callingUid = Binder.getCallingUid();
8111         long ident = Binder.clearCallingIdentity();
8112
8113         synchronized(this) {
8114             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8115             try {
8116                 if (localLOGV) Slog.v(TAG, "getAppTasks");
8117
8118                 final int N = mRecentTasks.size();
8119                 for (int i = 0; i < N; i++) {
8120                     TaskRecord tr = mRecentTasks.get(i);
8121                     // Skip tasks that do not match the caller.  We don't need to verify
8122                     // callingPackage, because we are also limiting to callingUid and know
8123                     // that will limit to the correct security sandbox.
8124                     if (tr.effectiveUid != callingUid) {
8125                         continue;
8126                     }
8127                     Intent intent = tr.getBaseIntent();
8128                     if (intent == null ||
8129                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8130                         continue;
8131                     }
8132                     ActivityManager.RecentTaskInfo taskInfo =
8133                             createRecentTaskInfoFromTaskRecord(tr);
8134                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8135                     list.add(taskImpl);
8136                 }
8137             } finally {
8138                 Binder.restoreCallingIdentity(ident);
8139             }
8140             return list;
8141         }
8142     }
8143
8144     @Override
8145     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8146         final int callingUid = Binder.getCallingUid();
8147         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8148
8149         synchronized(this) {
8150             if (localLOGV) Slog.v(
8151                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8152
8153             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8154                     callingUid);
8155
8156             // TODO: Improve with MRU list from all ActivityStacks.
8157             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8158         }
8159
8160         return list;
8161     }
8162
8163     /**
8164      * Creates a new RecentTaskInfo from a TaskRecord.
8165      */
8166     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8167         // Update the task description to reflect any changes in the task stack
8168         tr.updateTaskDescription();
8169
8170         // Compose the recent task info
8171         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8172         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8173         rti.persistentId = tr.taskId;
8174         rti.baseIntent = new Intent(tr.getBaseIntent());
8175         rti.origActivity = tr.origActivity;
8176         rti.description = tr.lastDescription;
8177         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8178         rti.userId = tr.userId;
8179         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8180         rti.firstActiveTime = tr.firstActiveTime;
8181         rti.lastActiveTime = tr.lastActiveTime;
8182         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8183         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8184         return rti;
8185     }
8186
8187     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8188         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8189                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8190         if (!allowed) {
8191             if (checkPermission(android.Manifest.permission.GET_TASKS,
8192                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8193                 // Temporary compatibility: some existing apps on the system image may
8194                 // still be requesting the old permission and not switched to the new
8195                 // one; if so, we'll still allow them full access.  This means we need
8196                 // to see if they are holding the old permission and are a system app.
8197                 try {
8198                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8199                         allowed = true;
8200                         Slog.w(TAG, caller + ": caller " + callingUid
8201                                 + " is using old GET_TASKS but privileged; allowing");
8202                     }
8203                 } catch (RemoteException e) {
8204                 }
8205             }
8206         }
8207         if (!allowed) {
8208             Slog.w(TAG, caller + ": caller " + callingUid
8209                     + " does not hold REAL_GET_TASKS; limiting output");
8210         }
8211         return allowed;
8212     }
8213
8214     @Override
8215     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8216         final int callingUid = Binder.getCallingUid();
8217         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8218                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8219
8220         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8221         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8222         synchronized (this) {
8223             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8224                     callingUid);
8225             final boolean detailed = checkCallingPermission(
8226                     android.Manifest.permission.GET_DETAILED_TASKS)
8227                     == PackageManager.PERMISSION_GRANTED;
8228
8229             final int N = mRecentTasks.size();
8230             ArrayList<ActivityManager.RecentTaskInfo> res
8231                     = new ArrayList<ActivityManager.RecentTaskInfo>(
8232                             maxNum < N ? maxNum : N);
8233
8234             final Set<Integer> includedUsers;
8235             if (includeProfiles) {
8236                 includedUsers = getProfileIdsLocked(userId);
8237             } else {
8238                 includedUsers = new HashSet<Integer>();
8239             }
8240             includedUsers.add(Integer.valueOf(userId));
8241
8242             for (int i=0; i<N && maxNum > 0; i++) {
8243                 TaskRecord tr = mRecentTasks.get(i);
8244                 // Only add calling user or related users recent tasks
8245                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8246                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8247                     continue;
8248                 }
8249
8250                 // Return the entry if desired by the caller.  We always return
8251                 // the first entry, because callers always expect this to be the
8252                 // foreground app.  We may filter others if the caller has
8253                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8254                 // we should exclude the entry.
8255
8256                 if (i == 0
8257                         || withExcluded
8258                         || (tr.intent == null)
8259                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8260                                 == 0)) {
8261                     if (!allowed) {
8262                         // If the caller doesn't have the GET_TASKS permission, then only
8263                         // allow them to see a small subset of tasks -- their own and home.
8264                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8265                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8266                             continue;
8267                         }
8268                     }
8269                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8270                         if (tr.stack != null && tr.stack.isHomeStack()) {
8271                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8272                             continue;
8273                         }
8274                     }
8275                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8276                         // Don't include auto remove tasks that are finished or finishing.
8277                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8278                                 + tr);
8279                         continue;
8280                     }
8281                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8282                             && !tr.isAvailable) {
8283                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8284                         continue;
8285                     }
8286
8287                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8288                     if (!detailed) {
8289                         rti.baseIntent.replaceExtras((Bundle)null);
8290                     }
8291
8292                     res.add(rti);
8293                     maxNum--;
8294                 }
8295             }
8296             return res;
8297         }
8298     }
8299
8300     TaskRecord recentTaskForIdLocked(int id) {
8301         final int N = mRecentTasks.size();
8302             for (int i=0; i<N; i++) {
8303                 TaskRecord tr = mRecentTasks.get(i);
8304                 if (tr.taskId == id) {
8305                     return tr;
8306                 }
8307             }
8308             return null;
8309     }
8310
8311     @Override
8312     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8313         synchronized (this) {
8314             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8315                     "getTaskThumbnail()");
8316             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8317             if (tr != null) {
8318                 return tr.getTaskThumbnailLocked();
8319             }
8320         }
8321         return null;
8322     }
8323
8324     @Override
8325     public int addAppTask(IBinder activityToken, Intent intent,
8326             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8327         final int callingUid = Binder.getCallingUid();
8328         final long callingIdent = Binder.clearCallingIdentity();
8329
8330         try {
8331             synchronized (this) {
8332                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8333                 if (r == null) {
8334                     throw new IllegalArgumentException("Activity does not exist; token="
8335                             + activityToken);
8336                 }
8337                 ComponentName comp = intent.getComponent();
8338                 if (comp == null) {
8339                     throw new IllegalArgumentException("Intent " + intent
8340                             + " must specify explicit component");
8341                 }
8342                 if (thumbnail.getWidth() != mThumbnailWidth
8343                         || thumbnail.getHeight() != mThumbnailHeight) {
8344                     throw new IllegalArgumentException("Bad thumbnail size: got "
8345                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8346                             + mThumbnailWidth + "x" + mThumbnailHeight);
8347                 }
8348                 if (intent.getSelector() != null) {
8349                     intent.setSelector(null);
8350                 }
8351                 if (intent.getSourceBounds() != null) {
8352                     intent.setSourceBounds(null);
8353                 }
8354                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8355                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8356                         // The caller has added this as an auto-remove task...  that makes no
8357                         // sense, so turn off auto-remove.
8358                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8359                     }
8360                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8361                     // Must be a new task.
8362                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8363                 }
8364                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8365                     mLastAddedTaskActivity = null;
8366                 }
8367                 ActivityInfo ainfo = mLastAddedTaskActivity;
8368                 if (ainfo == null) {
8369                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8370                             comp, 0, UserHandle.getUserId(callingUid));
8371                     if (ainfo.applicationInfo.uid != callingUid) {
8372                         throw new SecurityException(
8373                                 "Can't add task for another application: target uid="
8374                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8375                     }
8376                 }
8377
8378                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8379                         intent, description);
8380
8381                 int trimIdx = trimRecentsForTaskLocked(task, false);
8382                 if (trimIdx >= 0) {
8383                     // If this would have caused a trim, then we'll abort because that
8384                     // means it would be added at the end of the list but then just removed.
8385                     return INVALID_TASK_ID;
8386                 }
8387
8388                 final int N = mRecentTasks.size();
8389                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8390                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8391                     tr.removedFromRecents();
8392                 }
8393
8394                 task.inRecents = true;
8395                 mRecentTasks.add(task);
8396                 r.task.stack.addTask(task, false, false);
8397
8398                 task.setLastThumbnail(thumbnail);
8399                 task.freeLastThumbnail();
8400
8401                 return task.taskId;
8402             }
8403         } finally {
8404             Binder.restoreCallingIdentity(callingIdent);
8405         }
8406     }
8407
8408     @Override
8409     public Point getAppTaskThumbnailSize() {
8410         synchronized (this) {
8411             return new Point(mThumbnailWidth,  mThumbnailHeight);
8412         }
8413     }
8414
8415     @Override
8416     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8417         synchronized (this) {
8418             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8419             if (r != null) {
8420                 r.setTaskDescription(td);
8421                 r.task.updateTaskDescription();
8422             }
8423         }
8424     }
8425
8426     @Override
8427     public Bitmap getTaskDescriptionIcon(String filename) {
8428         if (!FileUtils.isValidExtFilename(filename)
8429                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8430             throw new IllegalArgumentException("Bad filename: " + filename);
8431         }
8432         return mTaskPersister.getTaskDescriptionIcon(filename);
8433     }
8434
8435     @Override
8436     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8437             throws RemoteException {
8438         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8439                 opts.getCustomInPlaceResId() == 0) {
8440             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8441                     "with valid animation");
8442         }
8443         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8444         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8445                 opts.getCustomInPlaceResId());
8446         mWindowManager.executeAppTransition();
8447     }
8448
8449     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8450         mRecentTasks.remove(tr);
8451         tr.removedFromRecents();
8452         ComponentName component = tr.getBaseIntent().getComponent();
8453         if (component == null) {
8454             Slog.w(TAG, "No component for base intent of task: " + tr);
8455             return;
8456         }
8457
8458         if (!killProcess) {
8459             return;
8460         }
8461
8462         // Determine if the process(es) for this task should be killed.
8463         final String pkg = component.getPackageName();
8464         ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8465         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8466         for (int i = 0; i < pmap.size(); i++) {
8467
8468             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8469             for (int j = 0; j < uids.size(); j++) {
8470                 ProcessRecord proc = uids.valueAt(j);
8471                 if (proc.userId != tr.userId) {
8472                     // Don't kill process for a different user.
8473                     continue;
8474                 }
8475                 if (proc == mHomeProcess) {
8476                     // Don't kill the home process along with tasks from the same package.
8477                     continue;
8478                 }
8479                 if (!proc.pkgList.containsKey(pkg)) {
8480                     // Don't kill process that is not associated with this task.
8481                     continue;
8482                 }
8483
8484                 for (int k = 0; k < proc.activities.size(); k++) {
8485                     TaskRecord otherTask = proc.activities.get(k).task;
8486                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8487                         // Don't kill process(es) that has an activity in a different task that is
8488                         // also in recents.
8489                         return;
8490                     }
8491                 }
8492
8493                 // Add process to kill list.
8494                 procsToKill.add(proc);
8495             }
8496         }
8497
8498         // Find any running services associated with this app and stop if needed.
8499         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8500
8501         // Kill the running processes.
8502         for (int i = 0; i < procsToKill.size(); i++) {
8503             ProcessRecord pr = procsToKill.get(i);
8504             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8505                 pr.kill("remove task", true);
8506             } else {
8507                 pr.waitingToKill = "remove task";
8508             }
8509         }
8510     }
8511
8512     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8513         // Remove all tasks with activities in the specified package from the list of recent tasks
8514         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8515             TaskRecord tr = mRecentTasks.get(i);
8516             if (tr.userId != userId) continue;
8517
8518             ComponentName cn = tr.intent.getComponent();
8519             if (cn != null && cn.getPackageName().equals(packageName)) {
8520                 // If the package name matches, remove the task.
8521                 removeTaskByIdLocked(tr.taskId, true);
8522             }
8523         }
8524     }
8525
8526     private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8527         final IPackageManager pm = AppGlobals.getPackageManager();
8528         final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8529
8530         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8531             TaskRecord tr = mRecentTasks.get(i);
8532             if (tr.userId != userId) continue;
8533
8534             ComponentName cn = tr.intent.getComponent();
8535             if (cn != null && cn.getPackageName().equals(packageName)) {
8536                 // Skip if component still exists in the package.
8537                 if (componentsKnownToExist.contains(cn)) continue;
8538
8539                 try {
8540                     ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8541                     if (info != null) {
8542                         componentsKnownToExist.add(cn);
8543                     } else {
8544                         removeTaskByIdLocked(tr.taskId, false);
8545                     }
8546                 } catch (RemoteException e) {
8547                     Log.e(TAG, "Activity info query failed. component=" + cn, e);
8548                 }
8549             }
8550         }
8551     }
8552
8553     /**
8554      * Removes the task with the specified task id.
8555      *
8556      * @param taskId Identifier of the task to be removed.
8557      * @param killProcess Kill any process associated with the task if possible.
8558      * @return Returns true if the given task was found and removed.
8559      */
8560     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8561         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8562         if (tr != null) {
8563             tr.removeTaskActivitiesLocked();
8564             cleanUpRemovedTaskLocked(tr, killProcess);
8565             if (tr.isPersistable) {
8566                 notifyTaskPersisterLocked(null, true);
8567             }
8568             return true;
8569         }
8570         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8571         return false;
8572     }
8573
8574     @Override
8575     public boolean removeTask(int taskId) {
8576         synchronized (this) {
8577             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8578                     "removeTask()");
8579             long ident = Binder.clearCallingIdentity();
8580             try {
8581                 return removeTaskByIdLocked(taskId, true);
8582             } finally {
8583                 Binder.restoreCallingIdentity(ident);
8584             }
8585         }
8586     }
8587
8588     /**
8589      * TODO: Add mController hook
8590      */
8591     @Override
8592     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8593         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8594                 "moveTaskToFront()");
8595
8596         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8597         synchronized(this) {
8598             moveTaskToFrontLocked(taskId, flags, options);
8599         }
8600     }
8601
8602     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8603         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8604                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8605             ActivityOptions.abort(options);
8606             return;
8607         }
8608         final long origId = Binder.clearCallingIdentity();
8609         try {
8610             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8611             if (task == null) {
8612                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8613                 return;
8614             }
8615             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8616                 mStackSupervisor.showLockTaskToast();
8617                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8618                 return;
8619             }
8620             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8621             if (prev != null && prev.isRecentsActivity()) {
8622                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8623             }
8624             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8625         } finally {
8626             Binder.restoreCallingIdentity(origId);
8627         }
8628         ActivityOptions.abort(options);
8629     }
8630
8631     @Override
8632     public void moveTaskToBack(int taskId) {
8633         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8634                 "moveTaskToBack()");
8635
8636         synchronized(this) {
8637             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8638             if (tr != null) {
8639                 if (tr == mStackSupervisor.mLockTaskModeTask) {
8640                     mStackSupervisor.showLockTaskToast();
8641                     return;
8642                 }
8643                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8644                 ActivityStack stack = tr.stack;
8645                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8646                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8647                             Binder.getCallingUid(), -1, -1, "Task to back")) {
8648                         return;
8649                     }
8650                 }
8651                 final long origId = Binder.clearCallingIdentity();
8652                 try {
8653                     stack.moveTaskToBackLocked(taskId);
8654                 } finally {
8655                     Binder.restoreCallingIdentity(origId);
8656                 }
8657             }
8658         }
8659     }
8660
8661     /**
8662      * Moves an activity, and all of the other activities within the same task, to the bottom
8663      * of the history stack.  The activity's order within the task is unchanged.
8664      * 
8665      * @param token A reference to the activity we wish to move
8666      * @param nonRoot If false then this only works if the activity is the root
8667      *                of a task; if true it will work for any activity in a task.
8668      * @return Returns true if the move completed, false if not.
8669      */
8670     @Override
8671     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8672         enforceNotIsolatedCaller("moveActivityTaskToBack");
8673         synchronized(this) {
8674             final long origId = Binder.clearCallingIdentity();
8675             try {
8676                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8677                 if (taskId >= 0) {
8678                     if ((mStackSupervisor.mLockTaskModeTask != null)
8679                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8680                         mStackSupervisor.showLockTaskToast();
8681                         return false;
8682                     }
8683                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8684                 }
8685             } finally {
8686                 Binder.restoreCallingIdentity(origId);
8687             }
8688         }
8689         return false;
8690     }
8691
8692     @Override
8693     public void moveTaskBackwards(int task) {
8694         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8695                 "moveTaskBackwards()");
8696
8697         synchronized(this) {
8698             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8699                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8700                 return;
8701             }
8702             final long origId = Binder.clearCallingIdentity();
8703             moveTaskBackwardsLocked(task);
8704             Binder.restoreCallingIdentity(origId);
8705         }
8706     }
8707
8708     private final void moveTaskBackwardsLocked(int task) {
8709         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8710     }
8711
8712     @Override
8713     public IBinder getHomeActivityToken() throws RemoteException {
8714         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8715                 "getHomeActivityToken()");
8716         synchronized (this) {
8717             return mStackSupervisor.getHomeActivityToken();
8718         }
8719     }
8720
8721     @Override
8722     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8723             IActivityContainerCallback callback) throws RemoteException {
8724         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8725                 "createActivityContainer()");
8726         synchronized (this) {
8727             if (parentActivityToken == null) {
8728                 throw new IllegalArgumentException("parent token must not be null");
8729             }
8730             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8731             if (r == null) {
8732                 return null;
8733             }
8734             if (callback == null) {
8735                 throw new IllegalArgumentException("callback must not be null");
8736             }
8737             return mStackSupervisor.createActivityContainer(r, callback);
8738         }
8739     }
8740
8741     @Override
8742     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8743         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                 "deleteActivityContainer()");
8745         synchronized (this) {
8746             mStackSupervisor.deleteActivityContainer(container);
8747         }
8748     }
8749
8750     @Override
8751     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8752         synchronized (this) {
8753             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8754             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8755                 return stack.mActivityContainer.getDisplayId();
8756             }
8757             return Display.DEFAULT_DISPLAY;
8758         }
8759     }
8760
8761     @Override
8762     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8763         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8764                 "moveTaskToStack()");
8765         if (stackId == HOME_STACK_ID) {
8766             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8767                     new RuntimeException("here").fillInStackTrace());
8768         }
8769         synchronized (this) {
8770             long ident = Binder.clearCallingIdentity();
8771             try {
8772                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8773                         + stackId + " toTop=" + toTop);
8774                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8775             } finally {
8776                 Binder.restoreCallingIdentity(ident);
8777             }
8778         }
8779     }
8780
8781     @Override
8782     public void resizeStack(int stackBoxId, Rect bounds) {
8783         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8784                 "resizeStackBox()");
8785         long ident = Binder.clearCallingIdentity();
8786         try {
8787             mWindowManager.resizeStack(stackBoxId, bounds);
8788         } finally {
8789             Binder.restoreCallingIdentity(ident);
8790         }
8791     }
8792
8793     @Override
8794     public List<StackInfo> getAllStackInfos() {
8795         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8796                 "getAllStackInfos()");
8797         long ident = Binder.clearCallingIdentity();
8798         try {
8799             synchronized (this) {
8800                 return mStackSupervisor.getAllStackInfosLocked();
8801             }
8802         } finally {
8803             Binder.restoreCallingIdentity(ident);
8804         }
8805     }
8806
8807     @Override
8808     public StackInfo getStackInfo(int stackId) {
8809         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8810                 "getStackInfo()");
8811         long ident = Binder.clearCallingIdentity();
8812         try {
8813             synchronized (this) {
8814                 return mStackSupervisor.getStackInfoLocked(stackId);
8815             }
8816         } finally {
8817             Binder.restoreCallingIdentity(ident);
8818         }
8819     }
8820
8821     @Override
8822     public boolean isInHomeStack(int taskId) {
8823         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8824                 "getStackInfo()");
8825         long ident = Binder.clearCallingIdentity();
8826         try {
8827             synchronized (this) {
8828                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8829                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8830             }
8831         } finally {
8832             Binder.restoreCallingIdentity(ident);
8833         }
8834     }
8835
8836     @Override
8837     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8838         synchronized(this) {
8839             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8840         }
8841     }
8842
8843     private boolean isLockTaskAuthorized(String pkg) {
8844         final DevicePolicyManager dpm = (DevicePolicyManager)
8845                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8846         try {
8847             int uid = mContext.getPackageManager().getPackageUid(pkg,
8848                     Binder.getCallingUserHandle().getIdentifier());
8849             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8850         } catch (NameNotFoundException e) {
8851             return false;
8852         }
8853     }
8854
8855     void startLockTaskMode(TaskRecord task) {
8856         final String pkg;
8857         synchronized (this) {
8858             pkg = task.intent.getComponent().getPackageName();
8859         }
8860         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8861         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8862             StatusBarManagerInternal statusBarManager = LocalServices.getService(
8863                     StatusBarManagerInternal.class);
8864             if (statusBarManager != null) {
8865                 statusBarManager.showScreenPinningRequest();
8866             }
8867             return;
8868         }
8869         long ident = Binder.clearCallingIdentity();
8870         try {
8871             synchronized (this) {
8872                 // Since we lost lock on task, make sure it is still there.
8873                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8874                 if (task != null) {
8875                     if (!isSystemInitiated
8876                             && ((mStackSupervisor.getFocusedStack() == null)
8877                                     || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8878                         throw new IllegalArgumentException("Invalid task, not in foreground");
8879                     }
8880                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8881                             "startLockTask");
8882                 }
8883             }
8884         } finally {
8885             Binder.restoreCallingIdentity(ident);
8886         }
8887     }
8888
8889     @Override
8890     public void startLockTaskMode(int taskId) {
8891         final TaskRecord task;
8892         long ident = Binder.clearCallingIdentity();
8893         try {
8894             synchronized (this) {
8895                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8896             }
8897         } finally {
8898             Binder.restoreCallingIdentity(ident);
8899         }
8900         if (task != null) {
8901             startLockTaskMode(task);
8902         }
8903     }
8904
8905     @Override
8906     public void startLockTaskMode(IBinder token) {
8907         final TaskRecord task;
8908         long ident = Binder.clearCallingIdentity();
8909         try {
8910             synchronized (this) {
8911                 final ActivityRecord r = ActivityRecord.forToken(token);
8912                 if (r == null) {
8913                     return;
8914                 }
8915                 task = r.task;
8916             }
8917         } finally {
8918             Binder.restoreCallingIdentity(ident);
8919         }
8920         if (task != null) {
8921             startLockTaskMode(task);
8922         }
8923     }
8924
8925     @Override
8926     public void startLockTaskModeOnCurrent() throws RemoteException {
8927         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8928                 "startLockTaskModeOnCurrent");
8929         long ident = Binder.clearCallingIdentity();
8930         try {
8931             ActivityRecord r = null;
8932             synchronized (this) {
8933                 r = mStackSupervisor.topRunningActivityLocked();
8934             }
8935             startLockTaskMode(r.task);
8936         } finally {
8937             Binder.restoreCallingIdentity(ident);
8938         }
8939     }
8940
8941     @Override
8942     public void stopLockTaskMode() {
8943         // Verify that the user matches the package of the intent for the TaskRecord
8944         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8945         // and stopLockTaskMode.
8946         final int callingUid = Binder.getCallingUid();
8947         if (callingUid != Process.SYSTEM_UID) {
8948             try {
8949                 String pkg =
8950                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8951                 int uid = mContext.getPackageManager().getPackageUid(pkg,
8952                         Binder.getCallingUserHandle().getIdentifier());
8953                 if (uid != callingUid) {
8954                     throw new SecurityException("Invalid uid, expected " + uid);
8955                 }
8956             } catch (NameNotFoundException e) {
8957                 Log.d(TAG, "stopLockTaskMode " + e);
8958                 return;
8959             }
8960         }
8961         long ident = Binder.clearCallingIdentity();
8962         try {
8963             Log.d(TAG, "stopLockTaskMode");
8964             // Stop lock task
8965             synchronized (this) {
8966                 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8967             }
8968         } finally {
8969             Binder.restoreCallingIdentity(ident);
8970         }
8971     }
8972
8973     @Override
8974     public void stopLockTaskModeOnCurrent() throws RemoteException {
8975         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8976                 "stopLockTaskModeOnCurrent");
8977         long ident = Binder.clearCallingIdentity();
8978         try {
8979             stopLockTaskMode();
8980         } finally {
8981             Binder.restoreCallingIdentity(ident);
8982         }
8983     }
8984
8985     @Override
8986     public boolean isInLockTaskMode() {
8987         synchronized (this) {
8988             return mStackSupervisor.isInLockTaskMode();
8989         }
8990     }
8991
8992     // =========================================================
8993     // CONTENT PROVIDERS
8994     // =========================================================
8995
8996     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8997         List<ProviderInfo> providers = null;
8998         try {
8999             providers = AppGlobals.getPackageManager().
9000                 queryContentProviders(app.processName, app.uid,
9001                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9002         } catch (RemoteException ex) {
9003         }
9004         if (DEBUG_MU)
9005             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9006         int userId = app.userId;
9007         if (providers != null) {
9008             int N = providers.size();
9009             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9010             for (int i=0; i<N; i++) {
9011                 ProviderInfo cpi =
9012                     (ProviderInfo)providers.get(i);
9013                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9014                         cpi.name, cpi.flags);
9015                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
9016                     // This is a singleton provider, but a user besides the
9017                     // default user is asking to initialize a process it runs
9018                     // in...  well, no, it doesn't actually run in this process,
9019                     // it runs in the process of the default user.  Get rid of it.
9020                     providers.remove(i);
9021                     N--;
9022                     i--;
9023                     continue;
9024                 }
9025
9026                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9027                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9028                 if (cpr == null) {
9029                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9030                     mProviderMap.putProviderByClass(comp, cpr);
9031                 }
9032                 if (DEBUG_MU)
9033                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9034                 app.pubProviders.put(cpi.name, cpr);
9035                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9036                     // Don't add this if it is a platform component that is marked
9037                     // to run in multiple processes, because this is actually
9038                     // part of the framework so doesn't make sense to track as a
9039                     // separate apk in the process.
9040                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9041                             mProcessStats);
9042                 }
9043                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9044             }
9045         }
9046         return providers;
9047     }
9048
9049     /**
9050      * Check if {@link ProcessRecord} has a possible chance at accessing the
9051      * given {@link ProviderInfo}. Final permission checking is always done
9052      * in {@link ContentProvider}.
9053      */
9054     private final String checkContentProviderPermissionLocked(
9055             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9056         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9057         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9058         boolean checkedGrants = false;
9059         if (checkUser) {
9060             // Looking for cross-user grants before enforcing the typical cross-users permissions
9061             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9062             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9063                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9064                     return null;
9065                 }
9066                 checkedGrants = true;
9067             }
9068             userId = handleIncomingUser(callingPid, callingUid, userId,
9069                     false, ALLOW_NON_FULL,
9070                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9071             if (userId != tmpTargetUserId) {
9072                 // When we actually went to determine the final targer user ID, this ended
9073                 // up different than our initial check for the authority.  This is because
9074                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9075                 // SELF.  So we need to re-check the grants again.
9076                 checkedGrants = false;
9077             }
9078         }
9079         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9080                 cpi.applicationInfo.uid, cpi.exported)
9081                 == PackageManager.PERMISSION_GRANTED) {
9082             return null;
9083         }
9084         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9085                 cpi.applicationInfo.uid, cpi.exported)
9086                 == PackageManager.PERMISSION_GRANTED) {
9087             return null;
9088         }
9089         
9090         PathPermission[] pps = cpi.pathPermissions;
9091         if (pps != null) {
9092             int i = pps.length;
9093             while (i > 0) {
9094                 i--;
9095                 PathPermission pp = pps[i];
9096                 String pprperm = pp.getReadPermission();
9097                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9098                         cpi.applicationInfo.uid, cpi.exported)
9099                         == PackageManager.PERMISSION_GRANTED) {
9100                     return null;
9101                 }
9102                 String ppwperm = pp.getWritePermission();
9103                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9104                         cpi.applicationInfo.uid, cpi.exported)
9105                         == PackageManager.PERMISSION_GRANTED) {
9106                     return null;
9107                 }
9108             }
9109         }
9110         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9111             return null;
9112         }
9113
9114         String msg;
9115         if (!cpi.exported) {
9116             msg = "Permission Denial: opening provider " + cpi.name
9117                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9118                     + ", uid=" + callingUid + ") that is not exported from uid "
9119                     + cpi.applicationInfo.uid;
9120         } else {
9121             msg = "Permission Denial: opening provider " + cpi.name
9122                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9123                     + ", uid=" + callingUid + ") requires "
9124                     + cpi.readPermission + " or " + cpi.writePermission;
9125         }
9126         Slog.w(TAG, msg);
9127         return msg;
9128     }
9129
9130     /**
9131      * Returns if the ContentProvider has granted a uri to callingUid
9132      */
9133     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9134         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9135         if (perms != null) {
9136             for (int i=perms.size()-1; i>=0; i--) {
9137                 GrantUri grantUri = perms.keyAt(i);
9138                 if (grantUri.sourceUserId == userId || !checkUser) {
9139                     if (matchesProvider(grantUri.uri, cpi)) {
9140                         return true;
9141                     }
9142                 }
9143             }
9144         }
9145         return false;
9146     }
9147
9148     /**
9149      * Returns true if the uri authority is one of the authorities specified in the provider.
9150      */
9151     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9152         String uriAuth = uri.getAuthority();
9153         String cpiAuth = cpi.authority;
9154         if (cpiAuth.indexOf(';') == -1) {
9155             return cpiAuth.equals(uriAuth);
9156         }
9157         String[] cpiAuths = cpiAuth.split(";");
9158         int length = cpiAuths.length;
9159         for (int i = 0; i < length; i++) {
9160             if (cpiAuths[i].equals(uriAuth)) return true;
9161         }
9162         return false;
9163     }
9164
9165     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9166             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9167         if (r != null) {
9168             for (int i=0; i<r.conProviders.size(); i++) {
9169                 ContentProviderConnection conn = r.conProviders.get(i);
9170                 if (conn.provider == cpr) {
9171                     if (DEBUG_PROVIDER) Slog.v(TAG,
9172                             "Adding provider requested by "
9173                             + r.processName + " from process "
9174                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9175                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9176                     if (stable) {
9177                         conn.stableCount++;
9178                         conn.numStableIncs++;
9179                     } else {
9180                         conn.unstableCount++;
9181                         conn.numUnstableIncs++;
9182                     }
9183                     return conn;
9184                 }
9185             }
9186             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9187             if (stable) {
9188                 conn.stableCount = 1;
9189                 conn.numStableIncs = 1;
9190             } else {
9191                 conn.unstableCount = 1;
9192                 conn.numUnstableIncs = 1;
9193             }
9194             cpr.connections.add(conn);
9195             r.conProviders.add(conn);
9196             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9197             return conn;
9198         }
9199         cpr.addExternalProcessHandleLocked(externalProcessToken);
9200         return null;
9201     }
9202
9203     boolean decProviderCountLocked(ContentProviderConnection conn,
9204             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9205         if (conn != null) {
9206             cpr = conn.provider;
9207             if (DEBUG_PROVIDER) Slog.v(TAG,
9208                     "Removing provider requested by "
9209                     + conn.client.processName + " from process "
9210                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9211                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9212             if (stable) {
9213                 conn.stableCount--;
9214             } else {
9215                 conn.unstableCount--;
9216             }
9217             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9218                 cpr.connections.remove(conn);
9219                 conn.client.conProviders.remove(conn);
9220                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9221                 return true;
9222             }
9223             return false;
9224         }
9225         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9226         return false;
9227     }
9228
9229     private void checkTime(long startTime, String where) {
9230         long now = SystemClock.elapsedRealtime();
9231         if ((now-startTime) > 1000) {
9232             // If we are taking more than a second, log about it.
9233             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9234         }
9235     }
9236
9237     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9238             String name, IBinder token, boolean stable, int userId) {
9239         ContentProviderRecord cpr;
9240         ContentProviderConnection conn = null;
9241         ProviderInfo cpi = null;
9242
9243         synchronized(this) {
9244             long startTime = SystemClock.elapsedRealtime();
9245
9246             ProcessRecord r = null;
9247             if (caller != null) {
9248                 r = getRecordForAppLocked(caller);
9249                 if (r == null) {
9250                     throw new SecurityException(
9251                             "Unable to find app for caller " + caller
9252                           + " (pid=" + Binder.getCallingPid()
9253                           + ") when getting content provider " + name);
9254                 }
9255             }
9256
9257             boolean checkCrossUser = true;
9258
9259             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9260
9261             // First check if this content provider has been published...
9262             cpr = mProviderMap.getProviderByName(name, userId);
9263             // If that didn't work, check if it exists for user 0 and then
9264             // verify that it's a singleton provider before using it.
9265             if (cpr == null && userId != UserHandle.USER_OWNER) {
9266                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9267                 if (cpr != null) {
9268                     cpi = cpr.info;
9269                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9270                             cpi.name, cpi.flags)
9271                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9272                         userId = UserHandle.USER_OWNER;
9273                         checkCrossUser = false;
9274                     } else {
9275                         cpr = null;
9276                         cpi = null;
9277                     }
9278                 }
9279             }
9280
9281             boolean providerRunning = cpr != null;
9282             if (providerRunning) {
9283                 cpi = cpr.info;
9284                 String msg;
9285                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9286                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9287                         != null) {
9288                     throw new SecurityException(msg);
9289                 }
9290                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9291
9292                 if (r != null && cpr.canRunHere(r)) {
9293                     // This provider has been published or is in the process
9294                     // of being published...  but it is also allowed to run
9295                     // in the caller's process, so don't make a connection
9296                     // and just let the caller instantiate its own instance.
9297                     ContentProviderHolder holder = cpr.newHolder(null);
9298                     // don't give caller the provider object, it needs
9299                     // to make its own.
9300                     holder.provider = null;
9301                     return holder;
9302                 }
9303
9304                 final long origId = Binder.clearCallingIdentity();
9305
9306                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9307
9308                 // In this case the provider instance already exists, so we can
9309                 // return it right away.
9310                 conn = incProviderCountLocked(r, cpr, token, stable);
9311                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9312                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9313                         // If this is a perceptible app accessing the provider,
9314                         // make sure to count it as being accessed and thus
9315                         // back up on the LRU list.  This is good because
9316                         // content providers are often expensive to start.
9317                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9318                         updateLruProcessLocked(cpr.proc, false, null);
9319                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9320                     }
9321                 }
9322
9323                 if (cpr.proc != null) {
9324                     if (false) {
9325                         if (cpr.name.flattenToShortString().equals(
9326                                 "com.android.providers.calendar/.CalendarProvider2")) {
9327                             Slog.v(TAG, "****************** KILLING "
9328                                 + cpr.name.flattenToShortString());
9329                             Process.killProcess(cpr.proc.pid);
9330                         }
9331                     }
9332                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9333                     boolean success = updateOomAdjLocked(cpr.proc);
9334                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9335                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9336                     // NOTE: there is still a race here where a signal could be
9337                     // pending on the process even though we managed to update its
9338                     // adj level.  Not sure what to do about this, but at least
9339                     // the race is now smaller.
9340                     if (!success) {
9341                         // Uh oh...  it looks like the provider's process
9342                         // has been killed on us.  We need to wait for a new
9343                         // process to be started, and make sure its death
9344                         // doesn't kill our process.
9345                         Slog.i(TAG,
9346                                 "Existing provider " + cpr.name.flattenToShortString()
9347                                 + " is crashing; detaching " + r);
9348                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9349                         checkTime(startTime, "getContentProviderImpl: before appDied");
9350                         appDiedLocked(cpr.proc);
9351                         checkTime(startTime, "getContentProviderImpl: after appDied");
9352                         if (!lastRef) {
9353                             // This wasn't the last ref our process had on
9354                             // the provider...  we have now been killed, bail.
9355                             return null;
9356                         }
9357                         providerRunning = false;
9358                         conn = null;
9359                     }
9360                 }
9361
9362                 Binder.restoreCallingIdentity(origId);
9363             }
9364
9365             boolean singleton;
9366             if (!providerRunning) {
9367                 try {
9368                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9369                     cpi = AppGlobals.getPackageManager().
9370                         resolveContentProvider(name,
9371                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9372                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9373                 } catch (RemoteException ex) {
9374                 }
9375                 if (cpi == null) {
9376                     return null;
9377                 }
9378                 // If the provider is a singleton AND
9379                 // (it's a call within the same user || the provider is a
9380                 // privileged app)
9381                 // Then allow connecting to the singleton provider
9382                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9383                         cpi.name, cpi.flags)
9384                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9385                 if (singleton) {
9386                     userId = UserHandle.USER_OWNER;
9387                 }
9388                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9389                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9390
9391                 String msg;
9392                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9393                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9394                         != null) {
9395                     throw new SecurityException(msg);
9396                 }
9397                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9398
9399                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9400                         && !cpi.processName.equals("system")) {
9401                     // If this content provider does not run in the system
9402                     // process, and the system is not yet ready to run other
9403                     // processes, then fail fast instead of hanging.
9404                     throw new IllegalArgumentException(
9405                             "Attempt to launch content provider before system ready");
9406                 }
9407
9408                 // Make sure that the user who owns this provider is running.  If not,
9409                 // we don't want to allow it to run.
9410                 if (!isUserRunningLocked(userId, false)) {
9411                     Slog.w(TAG, "Unable to launch app "
9412                             + cpi.applicationInfo.packageName + "/"
9413                             + cpi.applicationInfo.uid + " for provider "
9414                             + name + ": user " + userId + " is stopped");
9415                     return null;
9416                 }
9417
9418                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9419                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9420                 cpr = mProviderMap.getProviderByClass(comp, userId);
9421                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9422                 final boolean firstClass = cpr == null;
9423                 if (firstClass) {
9424                     final long ident = Binder.clearCallingIdentity();
9425                     try {
9426                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9427                         ApplicationInfo ai =
9428                             AppGlobals.getPackageManager().
9429                                 getApplicationInfo(
9430                                         cpi.applicationInfo.packageName,
9431                                         STOCK_PM_FLAGS, userId);
9432                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9433                         if (ai == null) {
9434                             Slog.w(TAG, "No package info for content provider "
9435                                     + cpi.name);
9436                             return null;
9437                         }
9438                         ai = getAppInfoForUser(ai, userId);
9439                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9440                     } catch (RemoteException ex) {
9441                         // pm is in same process, this will never happen.
9442                     } finally {
9443                         Binder.restoreCallingIdentity(ident);
9444                     }
9445                 }
9446
9447                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9448
9449                 if (r != null && cpr.canRunHere(r)) {
9450                     // If this is a multiprocess provider, then just return its
9451                     // info and allow the caller to instantiate it.  Only do
9452                     // this if the provider is the same user as the caller's
9453                     // process, or can run as root (so can be in any process).
9454                     return cpr.newHolder(null);
9455                 }
9456
9457                 if (DEBUG_PROVIDER) {
9458                     RuntimeException e = new RuntimeException("here");
9459                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9460                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9461                 }
9462
9463                 // This is single process, and our app is now connecting to it.
9464                 // See if we are already in the process of launching this
9465                 // provider.
9466                 final int N = mLaunchingProviders.size();
9467                 int i;
9468                 for (i=0; i<N; i++) {
9469                     if (mLaunchingProviders.get(i) == cpr) {
9470                         break;
9471                     }
9472                 }
9473
9474                 // If the provider is not already being launched, then get it
9475                 // started.
9476                 if (i >= N) {
9477                     final long origId = Binder.clearCallingIdentity();
9478
9479                     try {
9480                         // Content provider is now in use, its package can't be stopped.
9481                         try {
9482                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9483                             AppGlobals.getPackageManager().setPackageStoppedState(
9484                                     cpr.appInfo.packageName, false, userId);
9485                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9486                         } catch (RemoteException e) {
9487                         } catch (IllegalArgumentException e) {
9488                             Slog.w(TAG, "Failed trying to unstop package "
9489                                     + cpr.appInfo.packageName + ": " + e);
9490                         }
9491
9492                         // Use existing process if already started
9493                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9494                         ProcessRecord proc = getProcessRecordLocked(
9495                                 cpi.processName, cpr.appInfo.uid, false);
9496                         if (proc != null && proc.thread != null) {
9497                             if (DEBUG_PROVIDER) {
9498                                 Slog.d(TAG, "Installing in existing process " + proc);
9499                             }
9500                             if (!proc.pubProviders.containsKey(cpi.name)) {
9501                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
9502                                 proc.pubProviders.put(cpi.name, cpr);
9503                                 try {
9504                                     proc.thread.scheduleInstallProvider(cpi);
9505                                 } catch (RemoteException e) {
9506                                 }
9507                             }
9508                         } else {
9509                             checkTime(startTime, "getContentProviderImpl: before start process");
9510                             proc = startProcessLocked(cpi.processName,
9511                                     cpr.appInfo, false, 0, "content provider",
9512                                     new ComponentName(cpi.applicationInfo.packageName,
9513                                             cpi.name), false, false, false);
9514                             checkTime(startTime, "getContentProviderImpl: after start process");
9515                             if (proc == null) {
9516                                 Slog.w(TAG, "Unable to launch app "
9517                                         + cpi.applicationInfo.packageName + "/"
9518                                         + cpi.applicationInfo.uid + " for provider "
9519                                         + name + ": process is bad");
9520                                 return null;
9521                             }
9522                         }
9523                         cpr.launchingApp = proc;
9524                         mLaunchingProviders.add(cpr);
9525                     } finally {
9526                         Binder.restoreCallingIdentity(origId);
9527                     }
9528                 }
9529
9530                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9531
9532                 // Make sure the provider is published (the same provider class
9533                 // may be published under multiple names).
9534                 if (firstClass) {
9535                     mProviderMap.putProviderByClass(comp, cpr);
9536                 }
9537
9538                 mProviderMap.putProviderByName(name, cpr);
9539                 conn = incProviderCountLocked(r, cpr, token, stable);
9540                 if (conn != null) {
9541                     conn.waiting = true;
9542                 }
9543             }
9544             checkTime(startTime, "getContentProviderImpl: done!");
9545         }
9546
9547         // Wait for the provider to be published...
9548         synchronized (cpr) {
9549             while (cpr.provider == null) {
9550                 if (cpr.launchingApp == null) {
9551                     Slog.w(TAG, "Unable to launch app "
9552                             + cpi.applicationInfo.packageName + "/"
9553                             + cpi.applicationInfo.uid + " for provider "
9554                             + name + ": launching app became null");
9555                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9556                             UserHandle.getUserId(cpi.applicationInfo.uid),
9557                             cpi.applicationInfo.packageName,
9558                             cpi.applicationInfo.uid, name);
9559                     return null;
9560                 }
9561                 try {
9562                     if (DEBUG_MU) {
9563                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9564                                 + cpr.launchingApp);
9565                     }
9566                     if (conn != null) {
9567                         conn.waiting = true;
9568                     }
9569                     cpr.wait();
9570                 } catch (InterruptedException ex) {
9571                 } finally {
9572                     if (conn != null) {
9573                         conn.waiting = false;
9574                     }
9575                 }
9576             }
9577         }
9578         return cpr != null ? cpr.newHolder(conn) : null;
9579     }
9580
9581     @Override
9582     public final ContentProviderHolder getContentProvider(
9583             IApplicationThread caller, String name, int userId, boolean stable) {
9584         enforceNotIsolatedCaller("getContentProvider");
9585         if (caller == null) {
9586             String msg = "null IApplicationThread when getting content provider "
9587                     + name;
9588             Slog.w(TAG, msg);
9589             throw new SecurityException(msg);
9590         }
9591         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9592         // with cross-user grant.
9593         return getContentProviderImpl(caller, name, null, stable, userId);
9594     }
9595
9596     public ContentProviderHolder getContentProviderExternal(
9597             String name, int userId, IBinder token) {
9598         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9599             "Do not have permission in call getContentProviderExternal()");
9600         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9601                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9602         return getContentProviderExternalUnchecked(name, token, userId);
9603     }
9604
9605     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9606             IBinder token, int userId) {
9607         return getContentProviderImpl(null, name, token, true, userId);
9608     }
9609
9610     /**
9611      * Drop a content provider from a ProcessRecord's bookkeeping
9612      */
9613     public void removeContentProvider(IBinder connection, boolean stable) {
9614         enforceNotIsolatedCaller("removeContentProvider");
9615         long ident = Binder.clearCallingIdentity();
9616         try {
9617             synchronized (this) {
9618                 ContentProviderConnection conn;
9619                 try {
9620                     conn = (ContentProviderConnection)connection;
9621                 } catch (ClassCastException e) {
9622                     String msg ="removeContentProvider: " + connection
9623                             + " not a ContentProviderConnection";
9624                     Slog.w(TAG, msg);
9625                     throw new IllegalArgumentException(msg);
9626                 }
9627                 if (conn == null) {
9628                     throw new NullPointerException("connection is null");
9629                 }
9630                 if (decProviderCountLocked(conn, null, null, stable)) {
9631                     updateOomAdjLocked();
9632                 }
9633             }
9634         } finally {
9635             Binder.restoreCallingIdentity(ident);
9636         }
9637     }
9638
9639     public void removeContentProviderExternal(String name, IBinder token) {
9640         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9641             "Do not have permission in call removeContentProviderExternal()");
9642         int userId = UserHandle.getCallingUserId();
9643         long ident = Binder.clearCallingIdentity();
9644         try {
9645             removeContentProviderExternalUnchecked(name, token, userId);
9646         } finally {
9647             Binder.restoreCallingIdentity(ident);
9648         }
9649     }
9650
9651     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9652         synchronized (this) {
9653             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9654             if(cpr == null) {
9655                 //remove from mProvidersByClass
9656                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9657                 return;
9658             }
9659
9660             //update content provider record entry info
9661             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9662             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9663             if (localCpr.hasExternalProcessHandles()) {
9664                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9665                     updateOomAdjLocked();
9666                 } else {
9667                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9668                             + " with no external reference for token: "
9669                             + token + ".");
9670                 }
9671             } else {
9672                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9673                         + " with no external references.");
9674             }
9675         }
9676     }
9677     
9678     public final void publishContentProviders(IApplicationThread caller,
9679             List<ContentProviderHolder> providers) {
9680         if (providers == null) {
9681             return;
9682         }
9683
9684         enforceNotIsolatedCaller("publishContentProviders");
9685         synchronized (this) {
9686             final ProcessRecord r = getRecordForAppLocked(caller);
9687             if (DEBUG_MU)
9688                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9689             if (r == null) {
9690                 throw new SecurityException(
9691                         "Unable to find app for caller " + caller
9692                       + " (pid=" + Binder.getCallingPid()
9693                       + ") when publishing content providers");
9694             }
9695
9696             final long origId = Binder.clearCallingIdentity();
9697
9698             final int N = providers.size();
9699             for (int i=0; i<N; i++) {
9700                 ContentProviderHolder src = providers.get(i);
9701                 if (src == null || src.info == null || src.provider == null) {
9702                     continue;
9703                 }
9704                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9705                 if (DEBUG_MU)
9706                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9707                 if (dst != null) {
9708                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9709                     mProviderMap.putProviderByClass(comp, dst);
9710                     String names[] = dst.info.authority.split(";");
9711                     for (int j = 0; j < names.length; j++) {
9712                         mProviderMap.putProviderByName(names[j], dst);
9713                     }
9714
9715                     int NL = mLaunchingProviders.size();
9716                     int j;
9717                     for (j=0; j<NL; j++) {
9718                         if (mLaunchingProviders.get(j) == dst) {
9719                             mLaunchingProviders.remove(j);
9720                             j--;
9721                             NL--;
9722                         }
9723                     }
9724                     synchronized (dst) {
9725                         dst.provider = src.provider;
9726                         dst.proc = r;
9727                         dst.notifyAll();
9728                     }
9729                     updateOomAdjLocked(r);
9730                 }
9731             }
9732
9733             Binder.restoreCallingIdentity(origId);
9734         }
9735     }
9736
9737     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9738         ContentProviderConnection conn;
9739         try {
9740             conn = (ContentProviderConnection)connection;
9741         } catch (ClassCastException e) {
9742             String msg ="refContentProvider: " + connection
9743                     + " not a ContentProviderConnection";
9744             Slog.w(TAG, msg);
9745             throw new IllegalArgumentException(msg);
9746         }
9747         if (conn == null) {
9748             throw new NullPointerException("connection is null");
9749         }
9750
9751         synchronized (this) {
9752             if (stable > 0) {
9753                 conn.numStableIncs += stable;
9754             }
9755             stable = conn.stableCount + stable;
9756             if (stable < 0) {
9757                 throw new IllegalStateException("stableCount < 0: " + stable);
9758             }
9759
9760             if (unstable > 0) {
9761                 conn.numUnstableIncs += unstable;
9762             }
9763             unstable = conn.unstableCount + unstable;
9764             if (unstable < 0) {
9765                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9766             }
9767
9768             if ((stable+unstable) <= 0) {
9769                 throw new IllegalStateException("ref counts can't go to zero here: stable="
9770                         + stable + " unstable=" + unstable);
9771             }
9772             conn.stableCount = stable;
9773             conn.unstableCount = unstable;
9774             return !conn.dead;
9775         }
9776     }
9777
9778     public void unstableProviderDied(IBinder connection) {
9779         ContentProviderConnection conn;
9780         try {
9781             conn = (ContentProviderConnection)connection;
9782         } catch (ClassCastException e) {
9783             String msg ="refContentProvider: " + connection
9784                     + " not a ContentProviderConnection";
9785             Slog.w(TAG, msg);
9786             throw new IllegalArgumentException(msg);
9787         }
9788         if (conn == null) {
9789             throw new NullPointerException("connection is null");
9790         }
9791
9792         // Safely retrieve the content provider associated with the connection.
9793         IContentProvider provider;
9794         synchronized (this) {
9795             provider = conn.provider.provider;
9796         }
9797
9798         if (provider == null) {
9799             // Um, yeah, we're way ahead of you.
9800             return;
9801         }
9802
9803         // Make sure the caller is being honest with us.
9804         if (provider.asBinder().pingBinder()) {
9805             // Er, no, still looks good to us.
9806             synchronized (this) {
9807                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9808                         + " says " + conn + " died, but we don't agree");
9809                 return;
9810             }
9811         }
9812
9813         // Well look at that!  It's dead!
9814         synchronized (this) {
9815             if (conn.provider.provider != provider) {
9816                 // But something changed...  good enough.
9817                 return;
9818             }
9819
9820             ProcessRecord proc = conn.provider.proc;
9821             if (proc == null || proc.thread == null) {
9822                 // Seems like the process is already cleaned up.
9823                 return;
9824             }
9825
9826             // As far as we're concerned, this is just like receiving a
9827             // death notification...  just a bit prematurely.
9828             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9829                     + ") early provider death");
9830             final long ident = Binder.clearCallingIdentity();
9831             try {
9832                 appDiedLocked(proc);
9833             } finally {
9834                 Binder.restoreCallingIdentity(ident);
9835             }
9836         }
9837     }
9838
9839     @Override
9840     public void appNotRespondingViaProvider(IBinder connection) {
9841         enforceCallingPermission(
9842                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9843
9844         final ContentProviderConnection conn = (ContentProviderConnection) connection;
9845         if (conn == null) {
9846             Slog.w(TAG, "ContentProviderConnection is null");
9847             return;
9848         }
9849
9850         final ProcessRecord host = conn.provider.proc;
9851         if (host == null) {
9852             Slog.w(TAG, "Failed to find hosting ProcessRecord");
9853             return;
9854         }
9855
9856         final long token = Binder.clearCallingIdentity();
9857         try {
9858             appNotResponding(host, null, null, false, "ContentProvider not responding");
9859         } finally {
9860             Binder.restoreCallingIdentity(token);
9861         }
9862     }
9863
9864     public final void installSystemProviders() {
9865         List<ProviderInfo> providers;
9866         synchronized (this) {
9867             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9868             providers = generateApplicationProvidersLocked(app);
9869             if (providers != null) {
9870                 for (int i=providers.size()-1; i>=0; i--) {
9871                     ProviderInfo pi = (ProviderInfo)providers.get(i);
9872                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9873                         Slog.w(TAG, "Not installing system proc provider " + pi.name
9874                                 + ": not system .apk");
9875                         providers.remove(i);
9876                     }
9877                 }
9878             }
9879         }
9880         if (providers != null) {
9881             mSystemThread.installSystemProviders(providers);
9882         }
9883
9884         mCoreSettingsObserver = new CoreSettingsObserver(this);
9885
9886         //mUsageStatsService.monitorPackages();
9887     }
9888
9889     /**
9890      * Allows apps to retrieve the MIME type of a URI.
9891      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9892      * users, then it does not need permission to access the ContentProvider.
9893      * Either, it needs cross-user uri grants.
9894      *
9895      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9896      *
9897      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9898      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9899      */
9900     public String getProviderMimeType(Uri uri, int userId) {
9901         enforceNotIsolatedCaller("getProviderMimeType");
9902         final String name = uri.getAuthority();
9903         int callingUid = Binder.getCallingUid();
9904         int callingPid = Binder.getCallingPid();
9905         long ident = 0;
9906         boolean clearedIdentity = false;
9907         userId = unsafeConvertIncomingUser(userId);
9908         if (canClearIdentity(callingPid, callingUid, userId)) {
9909             clearedIdentity = true;
9910             ident = Binder.clearCallingIdentity();
9911         }
9912         ContentProviderHolder holder = null;
9913         try {
9914             holder = getContentProviderExternalUnchecked(name, null, userId);
9915             if (holder != null) {
9916                 return holder.provider.getType(uri);
9917             }
9918         } catch (RemoteException e) {
9919             Log.w(TAG, "Content provider dead retrieving " + uri, e);
9920             return null;
9921         } finally {
9922             // We need to clear the identity to call removeContentProviderExternalUnchecked
9923             if (!clearedIdentity) {
9924                 ident = Binder.clearCallingIdentity();
9925             }
9926             try {
9927                 if (holder != null) {
9928                     removeContentProviderExternalUnchecked(name, null, userId);
9929                 }
9930             } finally {
9931                 Binder.restoreCallingIdentity(ident);
9932             }
9933         }
9934
9935         return null;
9936     }
9937
9938     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9939         if (UserHandle.getUserId(callingUid) == userId) {
9940             return true;
9941         }
9942         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9943                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9944                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9945                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9946                 return true;
9947         }
9948         return false;
9949     }
9950
9951     // =========================================================
9952     // GLOBAL MANAGEMENT
9953     // =========================================================
9954
9955     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9956             boolean isolated, int isolatedUid) {
9957         String proc = customProcess != null ? customProcess : info.processName;
9958         BatteryStatsImpl.Uid.Proc ps = null;
9959         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9960         final int userId = UserHandle.getUserId(info.uid);
9961         int uid = info.uid;
9962         if (isolated) {
9963             if (isolatedUid == 0) {
9964                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9965                 while (true) {
9966                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9967                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9968                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9969                     }
9970                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9971                     mNextIsolatedProcessUid++;
9972                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9973                         // No process for this uid, use it.
9974                         break;
9975                     }
9976                     stepsLeft--;
9977                     if (stepsLeft <= 0) {
9978                         return null;
9979                     }
9980                 }
9981             } else {
9982                 // Special case for startIsolatedProcess (internal only), where
9983                 // the uid of the isolated process is specified by the caller.
9984                 uid = isolatedUid;
9985             }
9986         }
9987         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
9988         if (!mBooted && !mBooting
9989                 && userId == UserHandle.USER_OWNER
9990                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
9991             r.persistent = true;
9992         }
9993         return r;
9994     }
9995
9996     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9997             String abiOverride) {
9998         ProcessRecord app;
9999         if (!isolated) {
10000             app = getProcessRecordLocked(info.processName, info.uid, true);
10001         } else {
10002             app = null;
10003         }
10004
10005         if (app == null) {
10006             app = newProcessRecordLocked(info, null, isolated, 0);
10007             mProcessNames.put(info.processName, app.uid, app);
10008             if (isolated) {
10009                 mIsolatedProcesses.put(app.uid, app);
10010             }
10011             updateLruProcessLocked(app, false, null);
10012             updateOomAdjLocked();
10013         }
10014
10015         // This package really, really can not be stopped.
10016         try {
10017             AppGlobals.getPackageManager().setPackageStoppedState(
10018                     info.packageName, false, UserHandle.getUserId(app.uid));
10019         } catch (RemoteException e) {
10020         } catch (IllegalArgumentException e) {
10021             Slog.w(TAG, "Failed trying to unstop package "
10022                     + info.packageName + ": " + e);
10023         }
10024
10025         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10026             app.persistent = true;
10027             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10028         }
10029         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10030             mPersistentStartingProcesses.add(app);
10031             startProcessLocked(app, "added application", app.processName, abiOverride,
10032                     null /* entryPoint */, null /* entryPointArgs */);
10033         }
10034
10035         return app;
10036     }
10037
10038     public void unhandledBack() {
10039         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10040                 "unhandledBack()");
10041
10042         synchronized(this) {
10043             final long origId = Binder.clearCallingIdentity();
10044             try {
10045                 getFocusedStack().unhandledBackLocked();
10046             } finally {
10047                 Binder.restoreCallingIdentity(origId);
10048             }
10049         }
10050     }
10051
10052     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10053         enforceNotIsolatedCaller("openContentUri");
10054         final int userId = UserHandle.getCallingUserId();
10055         String name = uri.getAuthority();
10056         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10057         ParcelFileDescriptor pfd = null;
10058         if (cph != null) {
10059             // We record the binder invoker's uid in thread-local storage before
10060             // going to the content provider to open the file.  Later, in the code
10061             // that handles all permissions checks, we look for this uid and use
10062             // that rather than the Activity Manager's own uid.  The effect is that
10063             // we do the check against the caller's permissions even though it looks
10064             // to the content provider like the Activity Manager itself is making
10065             // the request.
10066             Binder token = new Binder();
10067             sCallerIdentity.set(new Identity(
10068                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10069             try {
10070                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10071             } catch (FileNotFoundException e) {
10072                 // do nothing; pfd will be returned null
10073             } finally {
10074                 // Ensure that whatever happens, we clean up the identity state
10075                 sCallerIdentity.remove();
10076                 // Ensure we're done with the provider.
10077                 removeContentProviderExternalUnchecked(name, null, userId);
10078             }
10079         } else {
10080             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10081         }
10082         return pfd;
10083     }
10084
10085     // Actually is sleeping or shutting down or whatever else in the future
10086     // is an inactive state.
10087     public boolean isSleepingOrShuttingDown() {
10088         return isSleeping() || mShuttingDown;
10089     }
10090
10091     public boolean isSleeping() {
10092         return mSleeping;
10093     }
10094
10095     void onWakefulnessChanged(int wakefulness) {
10096         synchronized(this) {
10097             mWakefulness = wakefulness;
10098             updateSleepIfNeededLocked();
10099         }
10100     }
10101
10102     void finishRunningVoiceLocked() {
10103         if (mRunningVoice) {
10104             mRunningVoice = false;
10105             updateSleepIfNeededLocked();
10106         }
10107     }
10108
10109     void updateSleepIfNeededLocked() {
10110         if (mSleeping && !shouldSleepLocked()) {
10111             mSleeping = false;
10112             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10113         } else if (!mSleeping && shouldSleepLocked()) {
10114             mSleeping = true;
10115             mStackSupervisor.goingToSleepLocked();
10116
10117             // Initialize the wake times of all processes.
10118             checkExcessivePowerUsageLocked(false);
10119             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10120             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10121             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10122         }
10123     }
10124
10125     private boolean shouldSleepLocked() {
10126         // Resume applications while running a voice interactor.
10127         if (mRunningVoice) {
10128             return false;
10129         }
10130
10131         switch (mWakefulness) {
10132             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10133             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10134                 // If we're interactive but applications are already paused then defer
10135                 // resuming them until the lock screen is hidden.
10136                 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10137             case PowerManagerInternal.WAKEFULNESS_DOZING:
10138                 // If we're dozing then pause applications whenever the lock screen is shown.
10139                 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10140             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10141             default:
10142                 // If we're asleep then pause applications unconditionally.
10143                 return true;
10144         }
10145     }
10146
10147     /** Pokes the task persister. */
10148     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10149         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10150             // Never persist the home stack.
10151             return;
10152         }
10153         mTaskPersister.wakeup(task, flush);
10154     }
10155
10156     /** Notifies all listeners when the task stack has changed. */
10157     void notifyTaskStackChangedLocked() {
10158         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10159         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10160         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10161     }
10162
10163     @Override
10164     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10165         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10166     }
10167
10168     @Override
10169     public boolean shutdown(int timeout) {
10170         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10171                 != PackageManager.PERMISSION_GRANTED) {
10172             throw new SecurityException("Requires permission "
10173                     + android.Manifest.permission.SHUTDOWN);
10174         }
10175
10176         boolean timedout = false;
10177
10178         synchronized(this) {
10179             mShuttingDown = true;
10180             updateEventDispatchingLocked();
10181             timedout = mStackSupervisor.shutdownLocked(timeout);
10182         }
10183
10184         mAppOpsService.shutdown();
10185         if (mUsageStatsService != null) {
10186             mUsageStatsService.prepareShutdown();
10187         }
10188         mBatteryStatsService.shutdown();
10189         synchronized (this) {
10190             mProcessStats.shutdownLocked();
10191             notifyTaskPersisterLocked(null, true);
10192         }
10193
10194         return timedout;
10195     }
10196
10197     public final void activitySlept(IBinder token) {
10198         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10199
10200         final long origId = Binder.clearCallingIdentity();
10201
10202         synchronized (this) {
10203             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10204             if (r != null) {
10205                 mStackSupervisor.activitySleptLocked(r);
10206             }
10207         }
10208
10209         Binder.restoreCallingIdentity(origId);
10210     }
10211
10212     private String lockScreenShownToString() {
10213         switch (mLockScreenShown) {
10214             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10215             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10216             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10217             default: return "Unknown=" + mLockScreenShown;
10218         }
10219     }
10220
10221     void logLockScreen(String msg) {
10222         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10223                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10224                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10225                 + " mSleeping=" + mSleeping);
10226     }
10227
10228     void startRunningVoiceLocked() {
10229         if (!mRunningVoice) {
10230             mRunningVoice = true;
10231             updateSleepIfNeededLocked();
10232         }
10233     }
10234
10235     private void updateEventDispatchingLocked() {
10236         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10237     }
10238
10239     public void setLockScreenShown(boolean shown) {
10240         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10241                 != PackageManager.PERMISSION_GRANTED) {
10242             throw new SecurityException("Requires permission "
10243                     + android.Manifest.permission.DEVICE_POWER);
10244         }
10245
10246         synchronized(this) {
10247             long ident = Binder.clearCallingIdentity();
10248             try {
10249                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10250                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10251                 updateSleepIfNeededLocked();
10252             } finally {
10253                 Binder.restoreCallingIdentity(ident);
10254             }
10255         }
10256     }
10257
10258     @Override
10259     public void stopAppSwitches() {
10260         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10261                 != PackageManager.PERMISSION_GRANTED) {
10262             throw new SecurityException("Requires permission "
10263                     + android.Manifest.permission.STOP_APP_SWITCHES);
10264         }
10265         
10266         synchronized(this) {
10267             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10268                     + APP_SWITCH_DELAY_TIME;
10269             mDidAppSwitch = false;
10270             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10271             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10272             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10273         }
10274     }
10275     
10276     public void resumeAppSwitches() {
10277         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10278                 != PackageManager.PERMISSION_GRANTED) {
10279             throw new SecurityException("Requires permission "
10280                     + android.Manifest.permission.STOP_APP_SWITCHES);
10281         }
10282         
10283         synchronized(this) {
10284             // Note that we don't execute any pending app switches... we will
10285             // let those wait until either the timeout, or the next start
10286             // activity request.
10287             mAppSwitchesAllowedTime = 0;
10288         }
10289     }
10290     
10291     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10292             int callingPid, int callingUid, String name) {
10293         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10294             return true;
10295         }
10296
10297         int perm = checkComponentPermission(
10298                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10299                 sourceUid, -1, true);
10300         if (perm == PackageManager.PERMISSION_GRANTED) {
10301             return true;
10302         }
10303
10304         // If the actual IPC caller is different from the logical source, then
10305         // also see if they are allowed to control app switches.
10306         if (callingUid != -1 && callingUid != sourceUid) {
10307             perm = checkComponentPermission(
10308                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10309                     callingUid, -1, true);
10310             if (perm == PackageManager.PERMISSION_GRANTED) {
10311                 return true;
10312             }
10313         }
10314
10315         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10316         return false;
10317     }
10318     
10319     public void setDebugApp(String packageName, boolean waitForDebugger,
10320             boolean persistent) {
10321         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10322                 "setDebugApp()");
10323
10324         long ident = Binder.clearCallingIdentity();
10325         try {
10326             // Note that this is not really thread safe if there are multiple
10327             // callers into it at the same time, but that's not a situation we
10328             // care about.
10329             if (persistent) {
10330                 final ContentResolver resolver = mContext.getContentResolver();
10331                 Settings.Global.putString(
10332                     resolver, Settings.Global.DEBUG_APP,
10333                     packageName);
10334                 Settings.Global.putInt(
10335                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10336                     waitForDebugger ? 1 : 0);
10337             }
10338
10339             synchronized (this) {
10340                 if (!persistent) {
10341                     mOrigDebugApp = mDebugApp;
10342                     mOrigWaitForDebugger = mWaitForDebugger;
10343                 }
10344                 mDebugApp = packageName;
10345                 mWaitForDebugger = waitForDebugger;
10346                 mDebugTransient = !persistent;
10347                 if (packageName != null) {
10348                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10349                             false, UserHandle.USER_ALL, "set debug app");
10350                 }
10351             }
10352         } finally {
10353             Binder.restoreCallingIdentity(ident);
10354         }
10355     }
10356
10357     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10358         synchronized (this) {
10359             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10360             if (!isDebuggable) {
10361                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10362                     throw new SecurityException("Process not debuggable: " + app.packageName);
10363                 }
10364             }
10365
10366             mOpenGlTraceApp = processName;
10367         }
10368     }
10369
10370     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10371         synchronized (this) {
10372             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10373             if (!isDebuggable) {
10374                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10375                     throw new SecurityException("Process not debuggable: " + app.packageName);
10376                 }
10377             }
10378             mProfileApp = processName;
10379             mProfileFile = profilerInfo.profileFile;
10380             if (mProfileFd != null) {
10381                 try {
10382                     mProfileFd.close();
10383                 } catch (IOException e) {
10384                 }
10385                 mProfileFd = null;
10386             }
10387             mProfileFd = profilerInfo.profileFd;
10388             mSamplingInterval = profilerInfo.samplingInterval;
10389             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10390             mProfileType = 0;
10391         }
10392     }
10393
10394     @Override
10395     public void setAlwaysFinish(boolean enabled) {
10396         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10397                 "setAlwaysFinish()");
10398
10399         Settings.Global.putInt(
10400                 mContext.getContentResolver(),
10401                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10402
10403         synchronized (this) {
10404             mAlwaysFinishActivities = enabled;
10405         }
10406     }
10407
10408     @Override
10409     public void setActivityController(IActivityController controller) {
10410         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10411                 "setActivityController()");
10412         synchronized (this) {
10413             mController = controller;
10414             Watchdog.getInstance().setActivityController(controller);
10415         }
10416     }
10417
10418     @Override
10419     public void setUserIsMonkey(boolean userIsMonkey) {
10420         synchronized (this) {
10421             synchronized (mPidsSelfLocked) {
10422                 final int callingPid = Binder.getCallingPid();
10423                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10424                 if (precessRecord == null) {
10425                     throw new SecurityException("Unknown process: " + callingPid);
10426                 }
10427                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10428                     throw new SecurityException("Only an instrumentation process "
10429                             + "with a UiAutomation can call setUserIsMonkey");
10430                 }
10431             }
10432             mUserIsMonkey = userIsMonkey;
10433         }
10434     }
10435
10436     @Override
10437     public boolean isUserAMonkey() {
10438         synchronized (this) {
10439             // If there is a controller also implies the user is a monkey.
10440             return (mUserIsMonkey || mController != null);
10441         }
10442     }
10443
10444     public void requestBugReport() {
10445         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10446         SystemProperties.set("ctl.start", "bugreport");
10447     }
10448
10449     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10450         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10451     }
10452
10453     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10454         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10455             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10456         }
10457         return KEY_DISPATCHING_TIMEOUT;
10458     }
10459
10460     @Override
10461     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10462         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10463                 != PackageManager.PERMISSION_GRANTED) {
10464             throw new SecurityException("Requires permission "
10465                     + android.Manifest.permission.FILTER_EVENTS);
10466         }
10467         ProcessRecord proc;
10468         long timeout;
10469         synchronized (this) {
10470             synchronized (mPidsSelfLocked) {
10471                 proc = mPidsSelfLocked.get(pid);
10472             }
10473             timeout = getInputDispatchingTimeoutLocked(proc);
10474         }
10475
10476         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10477             return -1;
10478         }
10479
10480         return timeout;
10481     }
10482
10483     /**
10484      * Handle input dispatching timeouts.
10485      * Returns whether input dispatching should be aborted or not.
10486      */
10487     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10488             final ActivityRecord activity, final ActivityRecord parent,
10489             final boolean aboveSystem, String reason) {
10490         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10491                 != PackageManager.PERMISSION_GRANTED) {
10492             throw new SecurityException("Requires permission "
10493                     + android.Manifest.permission.FILTER_EVENTS);
10494         }
10495
10496         final String annotation;
10497         if (reason == null) {
10498             annotation = "Input dispatching timed out";
10499         } else {
10500             annotation = "Input dispatching timed out (" + reason + ")";
10501         }
10502
10503         if (proc != null) {
10504             synchronized (this) {
10505                 if (proc.debugging) {
10506                     return false;
10507                 }
10508
10509                 if (mDidDexOpt) {
10510                     // Give more time since we were dexopting.
10511                     mDidDexOpt = false;
10512                     return false;
10513                 }
10514
10515                 if (proc.instrumentationClass != null) {
10516                     Bundle info = new Bundle();
10517                     info.putString("shortMsg", "keyDispatchingTimedOut");
10518                     info.putString("longMsg", annotation);
10519                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10520                     return true;
10521                 }
10522             }
10523             mHandler.post(new Runnable() {
10524                 @Override
10525                 public void run() {
10526                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10527                 }
10528             });
10529         }
10530
10531         return true;
10532     }
10533
10534     public Bundle getAssistContextExtras(int requestType) {
10535         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10536                 UserHandle.getCallingUserId());
10537         if (pae == null) {
10538             return null;
10539         }
10540         synchronized (pae) {
10541             while (!pae.haveResult) {
10542                 try {
10543                     pae.wait();
10544                 } catch (InterruptedException e) {
10545                 }
10546             }
10547             if (pae.result != null) {
10548                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10549             }
10550         }
10551         synchronized (this) {
10552             mPendingAssistExtras.remove(pae);
10553             mHandler.removeCallbacks(pae);
10554         }
10555         return pae.extras;
10556     }
10557
10558     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10559             int userHandle) {
10560         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10561                 "getAssistContextExtras()");
10562         PendingAssistExtras pae;
10563         Bundle extras = new Bundle();
10564         synchronized (this) {
10565             ActivityRecord activity = getFocusedStack().mResumedActivity;
10566             if (activity == null) {
10567                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10568                 return null;
10569             }
10570             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10571             if (activity.app == null || activity.app.thread == null) {
10572                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10573                 return null;
10574             }
10575             if (activity.app.pid == Binder.getCallingPid()) {
10576                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10577                 return null;
10578             }
10579             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10580             try {
10581                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10582                         requestType);
10583                 mPendingAssistExtras.add(pae);
10584                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10585             } catch (RemoteException e) {
10586                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10587                 return null;
10588             }
10589             return pae;
10590         }
10591     }
10592
10593     public void reportAssistContextExtras(IBinder token, Bundle extras) {
10594         PendingAssistExtras pae = (PendingAssistExtras)token;
10595         synchronized (pae) {
10596             pae.result = extras;
10597             pae.haveResult = true;
10598             pae.notifyAll();
10599             if (pae.intent == null) {
10600                 // Caller is just waiting for the result.
10601                 return;
10602             }
10603         }
10604
10605         // We are now ready to launch the assist activity.
10606         synchronized (this) {
10607             boolean exists = mPendingAssistExtras.remove(pae);
10608             mHandler.removeCallbacks(pae);
10609             if (!exists) {
10610                 // Timed out.
10611                 return;
10612             }
10613         }
10614         pae.intent.replaceExtras(extras);
10615         if (pae.hint != null) {
10616             pae.intent.putExtra(pae.hint, true);
10617         }
10618         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10619                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10620                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10621         closeSystemDialogs("assist");
10622         try {
10623             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10624         } catch (ActivityNotFoundException e) {
10625             Slog.w(TAG, "No activity to handle assist action.", e);
10626         }
10627     }
10628
10629     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10630         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10631     }
10632
10633     public void registerProcessObserver(IProcessObserver observer) {
10634         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10635                 "registerProcessObserver()");
10636         synchronized (this) {
10637             mProcessObservers.register(observer);
10638         }
10639     }
10640
10641     @Override
10642     public void unregisterProcessObserver(IProcessObserver observer) {
10643         synchronized (this) {
10644             mProcessObservers.unregister(observer);
10645         }
10646     }
10647
10648     @Override
10649     public boolean convertFromTranslucent(IBinder token) {
10650         final long origId = Binder.clearCallingIdentity();
10651         try {
10652             synchronized (this) {
10653                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10654                 if (r == null) {
10655                     return false;
10656                 }
10657                 final boolean translucentChanged = r.changeWindowTranslucency(true);
10658                 if (translucentChanged) {
10659                     r.task.stack.releaseBackgroundResources();
10660                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10661                 }
10662                 mWindowManager.setAppFullscreen(token, true);
10663                 return translucentChanged;
10664             }
10665         } finally {
10666             Binder.restoreCallingIdentity(origId);
10667         }
10668     }
10669
10670     @Override
10671     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10672         final long origId = Binder.clearCallingIdentity();
10673         try {
10674             synchronized (this) {
10675                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10676                 if (r == null) {
10677                     return false;
10678                 }
10679                 int index = r.task.mActivities.lastIndexOf(r);
10680                 if (index > 0) {
10681                     ActivityRecord under = r.task.mActivities.get(index - 1);
10682                     under.returningOptions = options;
10683                 }
10684                 final boolean translucentChanged = r.changeWindowTranslucency(false);
10685                 if (translucentChanged) {
10686                     r.task.stack.convertToTranslucent(r);
10687                 }
10688                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10689                 mWindowManager.setAppFullscreen(token, false);
10690                 return translucentChanged;
10691             }
10692         } finally {
10693             Binder.restoreCallingIdentity(origId);
10694         }
10695     }
10696
10697     @Override
10698     public boolean requestVisibleBehind(IBinder token, boolean visible) {
10699         final long origId = Binder.clearCallingIdentity();
10700         try {
10701             synchronized (this) {
10702                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10703                 if (r != null) {
10704                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10705                 }
10706             }
10707             return false;
10708         } finally {
10709             Binder.restoreCallingIdentity(origId);
10710         }
10711     }
10712
10713     @Override
10714     public boolean isBackgroundVisibleBehind(IBinder token) {
10715         final long origId = Binder.clearCallingIdentity();
10716         try {
10717             synchronized (this) {
10718                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10719                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10720                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10721                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10722                 return visible;
10723             }
10724         } finally {
10725             Binder.restoreCallingIdentity(origId);
10726         }
10727     }
10728
10729     @Override
10730     public ActivityOptions getActivityOptions(IBinder token) {
10731         final long origId = Binder.clearCallingIdentity();
10732         try {
10733             synchronized (this) {
10734                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10735                 if (r != null) {
10736                     final ActivityOptions activityOptions = r.pendingOptions;
10737                     r.pendingOptions = null;
10738                     return activityOptions;
10739                 }
10740                 return null;
10741             }
10742         } finally {
10743             Binder.restoreCallingIdentity(origId);
10744         }
10745     }
10746
10747     @Override
10748     public void setImmersive(IBinder token, boolean immersive) {
10749         synchronized(this) {
10750             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10751             if (r == null) {
10752                 throw new IllegalArgumentException();
10753             }
10754             r.immersive = immersive;
10755
10756             // update associated state if we're frontmost
10757             if (r == mFocusedActivity) {
10758                 if (DEBUG_IMMERSIVE) {
10759                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
10760                 }
10761                 applyUpdateLockStateLocked(r);
10762             }
10763         }
10764     }
10765
10766     @Override
10767     public boolean isImmersive(IBinder token) {
10768         synchronized (this) {
10769             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10770             if (r == null) {
10771                 throw new IllegalArgumentException();
10772             }
10773             return r.immersive;
10774         }
10775     }
10776
10777     public boolean isTopActivityImmersive() {
10778         enforceNotIsolatedCaller("startActivity");
10779         synchronized (this) {
10780             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10781             return (r != null) ? r.immersive : false;
10782         }
10783     }
10784
10785     @Override
10786     public boolean isTopOfTask(IBinder token) {
10787         synchronized (this) {
10788             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10789             if (r == null) {
10790                 throw new IllegalArgumentException();
10791             }
10792             return r.task.getTopActivity() == r;
10793         }
10794     }
10795
10796     public final void enterSafeMode() {
10797         synchronized(this) {
10798             // It only makes sense to do this before the system is ready
10799             // and started launching other packages.
10800             if (!mSystemReady) {
10801                 try {
10802                     AppGlobals.getPackageManager().enterSafeMode();
10803                 } catch (RemoteException e) {
10804                 }
10805             }
10806
10807             mSafeMode = true;
10808         }
10809     }
10810
10811     public final void showSafeModeOverlay() {
10812         View v = LayoutInflater.from(mContext).inflate(
10813                 com.android.internal.R.layout.safe_mode, null);
10814         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10815         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10816         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10817         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10818         lp.gravity = Gravity.BOTTOM | Gravity.START;
10819         lp.format = v.getBackground().getOpacity();
10820         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10821                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10822         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10823         ((WindowManager)mContext.getSystemService(
10824                 Context.WINDOW_SERVICE)).addView(v, lp);
10825     }
10826
10827     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10828         if (!(sender instanceof PendingIntentRecord)) {
10829             return;
10830         }
10831         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10832         synchronized (stats) {
10833             if (mBatteryStatsService.isOnBattery()) {
10834                 mBatteryStatsService.enforceCallingPermission();
10835                 PendingIntentRecord rec = (PendingIntentRecord)sender;
10836                 int MY_UID = Binder.getCallingUid();
10837                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10838                 BatteryStatsImpl.Uid.Pkg pkg =
10839                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10840                             sourcePkg != null ? sourcePkg : rec.key.packageName);
10841                 pkg.incWakeupsLocked();
10842             }
10843         }
10844     }
10845
10846     public boolean killPids(int[] pids, String pReason, boolean secure) {
10847         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10848             throw new SecurityException("killPids only available to the system");
10849         }
10850         String reason = (pReason == null) ? "Unknown" : pReason;
10851         // XXX Note: don't acquire main activity lock here, because the window
10852         // manager calls in with its locks held.
10853
10854         boolean killed = false;
10855         synchronized (mPidsSelfLocked) {
10856             int[] types = new int[pids.length];
10857             int worstType = 0;
10858             for (int i=0; i<pids.length; i++) {
10859                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10860                 if (proc != null) {
10861                     int type = proc.setAdj;
10862                     types[i] = type;
10863                     if (type > worstType) {
10864                         worstType = type;
10865                     }
10866                 }
10867             }
10868
10869             // If the worst oom_adj is somewhere in the cached proc LRU range,
10870             // then constrain it so we will kill all cached procs.
10871             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10872                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10873                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10874             }
10875
10876             // If this is not a secure call, don't let it kill processes that
10877             // are important.
10878             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10879                 worstType = ProcessList.SERVICE_ADJ;
10880             }
10881
10882             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10883             for (int i=0; i<pids.length; i++) {
10884                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10885                 if (proc == null) {
10886                     continue;
10887                 }
10888                 int adj = proc.setAdj;
10889                 if (adj >= worstType && !proc.killedByAm) {
10890                     proc.kill(reason, true);
10891                     killed = true;
10892                 }
10893             }
10894         }
10895         return killed;
10896     }
10897
10898     @Override
10899     public void killUid(int uid, String reason) {
10900         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10901             throw new SecurityException("killUid only available to the system");
10902         }
10903         synchronized (this) {
10904             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10905                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10906                     reason != null ? reason : "kill uid");
10907         }
10908     }
10909
10910     @Override
10911     public boolean killProcessesBelowForeground(String reason) {
10912         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10913             throw new SecurityException("killProcessesBelowForeground() only available to system");
10914         }
10915
10916         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10917     }
10918
10919     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10920         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10921             throw new SecurityException("killProcessesBelowAdj() only available to system");
10922         }
10923
10924         boolean killed = false;
10925         synchronized (mPidsSelfLocked) {
10926             final int size = mPidsSelfLocked.size();
10927             for (int i = 0; i < size; i++) {
10928                 final int pid = mPidsSelfLocked.keyAt(i);
10929                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10930                 if (proc == null) continue;
10931
10932                 final int adj = proc.setAdj;
10933                 if (adj > belowAdj && !proc.killedByAm) {
10934                     proc.kill(reason, true);
10935                     killed = true;
10936                 }
10937             }
10938         }
10939         return killed;
10940     }
10941
10942     @Override
10943     public void hang(final IBinder who, boolean allowRestart) {
10944         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10945                 != PackageManager.PERMISSION_GRANTED) {
10946             throw new SecurityException("Requires permission "
10947                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10948         }
10949
10950         final IBinder.DeathRecipient death = new DeathRecipient() {
10951             @Override
10952             public void binderDied() {
10953                 synchronized (this) {
10954                     notifyAll();
10955                 }
10956             }
10957         };
10958
10959         try {
10960             who.linkToDeath(death, 0);
10961         } catch (RemoteException e) {
10962             Slog.w(TAG, "hang: given caller IBinder is already dead.");
10963             return;
10964         }
10965
10966         synchronized (this) {
10967             Watchdog.getInstance().setAllowRestart(allowRestart);
10968             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10969             synchronized (death) {
10970                 while (who.isBinderAlive()) {
10971                     try {
10972                         death.wait();
10973                     } catch (InterruptedException e) {
10974                     }
10975                 }
10976             }
10977             Watchdog.getInstance().setAllowRestart(true);
10978         }
10979     }
10980
10981     @Override
10982     public void restart() {
10983         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10984                 != PackageManager.PERMISSION_GRANTED) {
10985             throw new SecurityException("Requires permission "
10986                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10987         }
10988
10989         Log.i(TAG, "Sending shutdown broadcast...");
10990
10991         BroadcastReceiver br = new BroadcastReceiver() {
10992             @Override public void onReceive(Context context, Intent intent) {
10993                 // Now the broadcast is done, finish up the low-level shutdown.
10994                 Log.i(TAG, "Shutting down activity manager...");
10995                 shutdown(10000);
10996                 Log.i(TAG, "Shutdown complete, restarting!");
10997                 Process.killProcess(Process.myPid());
10998                 System.exit(10);
10999             }
11000         };
11001
11002         // First send the high-level shut down broadcast.
11003         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11004         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11005         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11006         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11007         mContext.sendOrderedBroadcastAsUser(intent,
11008                 UserHandle.ALL, null, br, mHandler, 0, null, null);
11009         */
11010         br.onReceive(mContext, intent);
11011     }
11012
11013     private long getLowRamTimeSinceIdle(long now) {
11014         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11015     }
11016
11017     @Override
11018     public void performIdleMaintenance() {
11019         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11020                 != PackageManager.PERMISSION_GRANTED) {
11021             throw new SecurityException("Requires permission "
11022                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11023         }
11024
11025         synchronized (this) {
11026             final long now = SystemClock.uptimeMillis();
11027             final long timeSinceLastIdle = now - mLastIdleTime;
11028             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11029             mLastIdleTime = now;
11030             mLowRamTimeSinceLastIdle = 0;
11031             if (mLowRamStartTime != 0) {
11032                 mLowRamStartTime = now;
11033             }
11034
11035             StringBuilder sb = new StringBuilder(128);
11036             sb.append("Idle maintenance over ");
11037             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11038             sb.append(" low RAM for ");
11039             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11040             Slog.i(TAG, sb.toString());
11041
11042             // If at least 1/3 of our time since the last idle period has been spent
11043             // with RAM low, then we want to kill processes.
11044             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11045
11046             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11047                 ProcessRecord proc = mLruProcesses.get(i);
11048                 if (proc.notCachedSinceIdle) {
11049                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11050                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11051                         if (doKilling && proc.initialIdlePss != 0
11052                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11053                             sb = new StringBuilder(128);
11054                             sb.append("Kill");
11055                             sb.append(proc.processName);
11056                             sb.append(" in idle maint: pss=");
11057                             sb.append(proc.lastPss);
11058                             sb.append(", initialPss=");
11059                             sb.append(proc.initialIdlePss);
11060                             sb.append(", period=");
11061                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11062                             sb.append(", lowRamPeriod=");
11063                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11064                             Slog.wtfQuiet(TAG, sb.toString());
11065                             proc.kill("idle maint (pss " + proc.lastPss
11066                                     + " from " + proc.initialIdlePss + ")", true);
11067                         }
11068                     }
11069                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11070                     proc.notCachedSinceIdle = true;
11071                     proc.initialIdlePss = 0;
11072                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11073                             mTestPssMode, isSleeping(), now);
11074                 }
11075             }
11076
11077             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11078             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11079         }
11080     }
11081
11082     private void retrieveSettings() {
11083         final ContentResolver resolver = mContext.getContentResolver();
11084         String debugApp = Settings.Global.getString(
11085             resolver, Settings.Global.DEBUG_APP);
11086         boolean waitForDebugger = Settings.Global.getInt(
11087             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11088         boolean alwaysFinishActivities = Settings.Global.getInt(
11089             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11090         boolean forceRtl = Settings.Global.getInt(
11091                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11092         // Transfer any global setting for forcing RTL layout, into a System Property
11093         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11094
11095         Configuration configuration = new Configuration();
11096         Settings.System.getConfiguration(resolver, configuration);
11097         if (forceRtl) {
11098             // This will take care of setting the correct layout direction flags
11099             configuration.setLayoutDirection(configuration.locale);
11100         }
11101
11102         synchronized (this) {
11103             mDebugApp = mOrigDebugApp = debugApp;
11104             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11105             mAlwaysFinishActivities = alwaysFinishActivities;
11106             // This happens before any activities are started, so we can
11107             // change mConfiguration in-place.
11108             updateConfigurationLocked(configuration, null, false, true);
11109             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11110         }
11111     }
11112
11113     /** Loads resources after the current configuration has been set. */
11114     private void loadResourcesOnSystemReady() {
11115         final Resources res = mContext.getResources();
11116         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11117         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11118         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11119     }
11120
11121     public boolean testIsSystemReady() {
11122         // no need to synchronize(this) just to read & return the value
11123         return mSystemReady;
11124     }
11125
11126     private static File getCalledPreBootReceiversFile() {
11127         File dataDir = Environment.getDataDirectory();
11128         File systemDir = new File(dataDir, "system");
11129         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11130         return fname;
11131     }
11132
11133     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11134         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11135         File file = getCalledPreBootReceiversFile();
11136         FileInputStream fis = null;
11137         try {
11138             fis = new FileInputStream(file);
11139             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11140             int fvers = dis.readInt();
11141             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11142                 String vers = dis.readUTF();
11143                 String codename = dis.readUTF();
11144                 String build = dis.readUTF();
11145                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11146                         && android.os.Build.VERSION.CODENAME.equals(codename)
11147                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11148                     int num = dis.readInt();
11149                     while (num > 0) {
11150                         num--;
11151                         String pkg = dis.readUTF();
11152                         String cls = dis.readUTF();
11153                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11154                     }
11155                 }
11156             }
11157         } catch (FileNotFoundException e) {
11158         } catch (IOException e) {
11159             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11160         } finally {
11161             if (fis != null) {
11162                 try {
11163                     fis.close();
11164                 } catch (IOException e) {
11165                 }
11166             }
11167         }
11168         return lastDoneReceivers;
11169     }
11170
11171     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11172         File file = getCalledPreBootReceiversFile();
11173         FileOutputStream fos = null;
11174         DataOutputStream dos = null;
11175         try {
11176             fos = new FileOutputStream(file);
11177             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11178             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11179             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11180             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11181             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11182             dos.writeInt(list.size());
11183             for (int i=0; i<list.size(); i++) {
11184                 dos.writeUTF(list.get(i).getPackageName());
11185                 dos.writeUTF(list.get(i).getClassName());
11186             }
11187         } catch (IOException e) {
11188             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11189             file.delete();
11190         } finally {
11191             FileUtils.sync(fos);
11192             if (dos != null) {
11193                 try {
11194                     dos.close();
11195                 } catch (IOException e) {
11196                     // TODO Auto-generated catch block
11197                     e.printStackTrace();
11198                 }
11199             }
11200         }
11201     }
11202
11203     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11204             ArrayList<ComponentName> doneReceivers, int userId) {
11205         boolean waitingUpdate = false;
11206         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11207         List<ResolveInfo> ris = null;
11208         try {
11209             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11210                     intent, null, 0, userId);
11211         } catch (RemoteException e) {
11212         }
11213         if (ris != null) {
11214             for (int i=ris.size()-1; i>=0; i--) {
11215                 if ((ris.get(i).activityInfo.applicationInfo.flags
11216                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
11217                     ris.remove(i);
11218                 }
11219             }
11220             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11221
11222             // For User 0, load the version number. When delivering to a new user, deliver
11223             // to all receivers.
11224             if (userId == UserHandle.USER_OWNER) {
11225                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11226                 for (int i=0; i<ris.size(); i++) {
11227                     ActivityInfo ai = ris.get(i).activityInfo;
11228                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
11229                     if (lastDoneReceivers.contains(comp)) {
11230                         // We already did the pre boot receiver for this app with the current
11231                         // platform version, so don't do it again...
11232                         ris.remove(i);
11233                         i--;
11234                         // ...however, do keep it as one that has been done, so we don't
11235                         // forget about it when rewriting the file of last done receivers.
11236                         doneReceivers.add(comp);
11237                     }
11238                 }
11239             }
11240
11241             // If primary user, send broadcast to all available users, else just to userId
11242             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11243                     : new int[] { userId };
11244             for (int i = 0; i < ris.size(); i++) {
11245                 ActivityInfo ai = ris.get(i).activityInfo;
11246                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11247                 doneReceivers.add(comp);
11248                 intent.setComponent(comp);
11249                 for (int j=0; j<users.length; j++) {
11250                     IIntentReceiver finisher = null;
11251                     // On last receiver and user, set up a completion callback
11252                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11253                         finisher = new IIntentReceiver.Stub() {
11254                             public void performReceive(Intent intent, int resultCode,
11255                                     String data, Bundle extras, boolean ordered,
11256                                     boolean sticky, int sendingUser) {
11257                                 // The raw IIntentReceiver interface is called
11258                                 // with the AM lock held, so redispatch to
11259                                 // execute our code without the lock.
11260                                 mHandler.post(onFinishCallback);
11261                             }
11262                         };
11263                     }
11264                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
11265                             + " for user " + users[j]);
11266                     broadcastIntentLocked(null, null, intent, null, finisher,
11267                             0, null, null, null, AppOpsManager.OP_NONE,
11268                             true, false, MY_PID, Process.SYSTEM_UID,
11269                             users[j]);
11270                     if (finisher != null) {
11271                         waitingUpdate = true;
11272                     }
11273                 }
11274             }
11275         }
11276
11277         return waitingUpdate;
11278     }
11279
11280     public void systemReady(final Runnable goingCallback) {
11281         synchronized(this) {
11282             if (mSystemReady) {
11283                 // If we're done calling all the receivers, run the next "boot phase" passed in
11284                 // by the SystemServer
11285                 if (goingCallback != null) {
11286                     goingCallback.run();
11287                 }
11288                 return;
11289             }
11290
11291             // Make sure we have the current profile info, since it is needed for
11292             // security checks.
11293             updateCurrentProfileIdsLocked();
11294
11295             if (mRecentTasks == null) {
11296                 mRecentTasks = mTaskPersister.restoreTasksLocked();
11297                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
11298                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11299                 mTaskPersister.startPersisting();
11300             }
11301
11302             // Check to see if there are any update receivers to run.
11303             if (!mDidUpdate) {
11304                 if (mWaitingUpdate) {
11305                     return;
11306                 }
11307                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11308                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11309                     public void run() {
11310                         synchronized (ActivityManagerService.this) {
11311                             mDidUpdate = true;
11312                         }
11313                         writeLastDonePreBootReceivers(doneReceivers);
11314                         showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11315                                 false);
11316                         systemReady(goingCallback);
11317                     }
11318                 }, doneReceivers, UserHandle.USER_OWNER);
11319
11320                 if (mWaitingUpdate) {
11321                     return;
11322                 }
11323                 mDidUpdate = true;
11324             }
11325
11326             mAppOpsService.systemReady();
11327             mSystemReady = true;
11328         }
11329
11330         ArrayList<ProcessRecord> procsToKill = null;
11331         synchronized(mPidsSelfLocked) {
11332             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11333                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11334                 if (!isAllowedWhileBooting(proc.info)){
11335                     if (procsToKill == null) {
11336                         procsToKill = new ArrayList<ProcessRecord>();
11337                     }
11338                     procsToKill.add(proc);
11339                 }
11340             }
11341         }
11342         
11343         synchronized(this) {
11344             if (procsToKill != null) {
11345                 for (int i=procsToKill.size()-1; i>=0; i--) {
11346                     ProcessRecord proc = procsToKill.get(i);
11347                     Slog.i(TAG, "Removing system update proc: " + proc);
11348                     removeProcessLocked(proc, true, false, "system update done");
11349                 }
11350             }
11351             
11352             // Now that we have cleaned up any update processes, we
11353             // are ready to start launching real processes and know that
11354             // we won't trample on them any more.
11355             mProcessesReady = true;
11356         }
11357         
11358         Slog.i(TAG, "System now ready");
11359         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11360             SystemClock.uptimeMillis());
11361
11362         synchronized(this) {
11363             // Make sure we have no pre-ready processes sitting around.
11364             
11365             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11366                 ResolveInfo ri = mContext.getPackageManager()
11367                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11368                                 STOCK_PM_FLAGS);
11369                 CharSequence errorMsg = null;
11370                 if (ri != null) {
11371                     ActivityInfo ai = ri.activityInfo;
11372                     ApplicationInfo app = ai.applicationInfo;
11373                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11374                         mTopAction = Intent.ACTION_FACTORY_TEST;
11375                         mTopData = null;
11376                         mTopComponent = new ComponentName(app.packageName,
11377                                 ai.name);
11378                     } else {
11379                         errorMsg = mContext.getResources().getText(
11380                                 com.android.internal.R.string.factorytest_not_system);
11381                     }
11382                 } else {
11383                     errorMsg = mContext.getResources().getText(
11384                             com.android.internal.R.string.factorytest_no_action);
11385                 }
11386                 if (errorMsg != null) {
11387                     mTopAction = null;
11388                     mTopData = null;
11389                     mTopComponent = null;
11390                     Message msg = Message.obtain();
11391                     msg.what = SHOW_FACTORY_ERROR_MSG;
11392                     msg.getData().putCharSequence("msg", errorMsg);
11393                     mUiHandler.sendMessage(msg);
11394                 }
11395             }
11396         }
11397
11398         retrieveSettings();
11399         loadResourcesOnSystemReady();
11400
11401         synchronized (this) {
11402             readGrantedUriPermissionsLocked();
11403         }
11404
11405         if (goingCallback != null) goingCallback.run();
11406
11407         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11408                 Integer.toString(mCurrentUserId), mCurrentUserId);
11409         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11410                 Integer.toString(mCurrentUserId), mCurrentUserId);
11411         mSystemServiceManager.startUser(mCurrentUserId);
11412
11413         synchronized (this) {
11414             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11415                 try {
11416                     List apps = AppGlobals.getPackageManager().
11417                         getPersistentApplications(STOCK_PM_FLAGS);
11418                     if (apps != null) {
11419                         int N = apps.size();
11420                         int i;
11421                         for (i=0; i<N; i++) {
11422                             ApplicationInfo info
11423                                 = (ApplicationInfo)apps.get(i);
11424                             if (info != null &&
11425                                     !info.packageName.equals("android")) {
11426                                 addAppLocked(info, false, null /* ABI override */);
11427                             }
11428                         }
11429                     }
11430                 } catch (RemoteException ex) {
11431                     // pm is in same process, this will never happen.
11432                 }
11433             }
11434
11435             // Start up initial activity.
11436             mBooting = true;
11437             startHomeActivityLocked(mCurrentUserId, "systemReady");
11438
11439             try {
11440                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11441                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11442                             + " data partition or your device will be unstable.");
11443                     mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11444                 }
11445             } catch (RemoteException e) {
11446             }
11447
11448             if (!Build.isFingerprintConsistent()) {
11449                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11450                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11451             }
11452
11453             long ident = Binder.clearCallingIdentity();
11454             try {
11455                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11456                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11457                         | Intent.FLAG_RECEIVER_FOREGROUND);
11458                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11459                 broadcastIntentLocked(null, null, intent,
11460                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11461                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11462                 intent = new Intent(Intent.ACTION_USER_STARTING);
11463                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11464                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11465                 broadcastIntentLocked(null, null, intent,
11466                         null, new IIntentReceiver.Stub() {
11467                             @Override
11468                             public void performReceive(Intent intent, int resultCode, String data,
11469                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11470                                     throws RemoteException {
11471                             }
11472                         }, 0, null, null,
11473                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11474                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11475             } catch (Throwable t) {
11476                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11477             } finally {
11478                 Binder.restoreCallingIdentity(ident);
11479             }
11480             mStackSupervisor.resumeTopActivitiesLocked();
11481             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11482         }
11483     }
11484
11485     private boolean makeAppCrashingLocked(ProcessRecord app,
11486             String shortMsg, String longMsg, String stackTrace) {
11487         app.crashing = true;
11488         app.crashingReport = generateProcessError(app,
11489                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11490         startAppProblemLocked(app);
11491         app.stopFreezingAllLocked();
11492         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11493     }
11494
11495     private void makeAppNotRespondingLocked(ProcessRecord app,
11496             String activity, String shortMsg, String longMsg) {
11497         app.notResponding = true;
11498         app.notRespondingReport = generateProcessError(app,
11499                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11500                 activity, shortMsg, longMsg, null);
11501         startAppProblemLocked(app);
11502         app.stopFreezingAllLocked();
11503     }
11504     
11505     /**
11506      * Generate a process error record, suitable for attachment to a ProcessRecord.
11507      * 
11508      * @param app The ProcessRecord in which the error occurred.
11509      * @param condition Crashing, Application Not Responding, etc.  Values are defined in 
11510      *                      ActivityManager.AppErrorStateInfo
11511      * @param activity The activity associated with the crash, if known.
11512      * @param shortMsg Short message describing the crash.
11513      * @param longMsg Long message describing the crash.
11514      * @param stackTrace Full crash stack trace, may be null.
11515      *
11516      * @return Returns a fully-formed AppErrorStateInfo record.
11517      */
11518     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 
11519             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11520         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11521
11522         report.condition = condition;
11523         report.processName = app.processName;
11524         report.pid = app.pid;
11525         report.uid = app.info.uid;
11526         report.tag = activity;
11527         report.shortMsg = shortMsg;
11528         report.longMsg = longMsg;
11529         report.stackTrace = stackTrace;
11530
11531         return report;
11532     }
11533
11534     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11535         synchronized (this) {
11536             app.crashing = false;
11537             app.crashingReport = null;
11538             app.notResponding = false;
11539             app.notRespondingReport = null;
11540             if (app.anrDialog == fromDialog) {
11541                 app.anrDialog = null;
11542             }
11543             if (app.waitDialog == fromDialog) {
11544                 app.waitDialog = null;
11545             }
11546             if (app.pid > 0 && app.pid != MY_PID) {
11547                 handleAppCrashLocked(app, null, null, null);
11548                 app.kill("user request after error", true);
11549             }
11550         }
11551     }
11552
11553     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11554             String stackTrace) {
11555         long now = SystemClock.uptimeMillis();
11556
11557         Long crashTime;
11558         if (!app.isolated) {
11559             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11560         } else {
11561             crashTime = null;
11562         }
11563         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11564             // This process loses!
11565             Slog.w(TAG, "Process " + app.info.processName
11566                     + " has crashed too many times: killing!");
11567             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11568                     app.userId, app.info.processName, app.uid);
11569             mStackSupervisor.handleAppCrashLocked(app);
11570             if (!app.persistent) {
11571                 // We don't want to start this process again until the user
11572                 // explicitly does so...  but for persistent process, we really
11573                 // need to keep it running.  If a persistent process is actually
11574                 // repeatedly crashing, then badness for everyone.
11575                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11576                         app.info.processName);
11577                 if (!app.isolated) {
11578                     // XXX We don't have a way to mark isolated processes
11579                     // as bad, since they don't have a peristent identity.
11580                     mBadProcesses.put(app.info.processName, app.uid,
11581                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11582                     mProcessCrashTimes.remove(app.info.processName, app.uid);
11583                 }
11584                 app.bad = true;
11585                 app.removed = true;
11586                 // Don't let services in this process be restarted and potentially
11587                 // annoy the user repeatedly.  Unless it is persistent, since those
11588                 // processes run critical code.
11589                 removeProcessLocked(app, false, false, "crash");
11590                 mStackSupervisor.resumeTopActivitiesLocked();
11591                 return false;
11592             }
11593             mStackSupervisor.resumeTopActivitiesLocked();
11594         } else {
11595             mStackSupervisor.finishTopRunningActivityLocked(app);
11596         }
11597
11598         // Bump up the crash count of any services currently running in the proc.
11599         for (int i=app.services.size()-1; i>=0; i--) {
11600             // Any services running in the application need to be placed
11601             // back in the pending list.
11602             ServiceRecord sr = app.services.valueAt(i);
11603             sr.crashCount++;
11604         }
11605
11606         // If the crashing process is what we consider to be the "home process" and it has been
11607         // replaced by a third-party app, clear the package preferred activities from packages
11608         // with a home activity running in the process to prevent a repeatedly crashing app
11609         // from blocking the user to manually clear the list.
11610         final ArrayList<ActivityRecord> activities = app.activities;
11611         if (app == mHomeProcess && activities.size() > 0
11612                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11613             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11614                 final ActivityRecord r = activities.get(activityNdx);
11615                 if (r.isHomeActivity()) {
11616                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11617                     try {
11618                         ActivityThread.getPackageManager()
11619                                 .clearPackagePreferredActivities(r.packageName);
11620                     } catch (RemoteException c) {
11621                         // pm is in same process, this will never happen.
11622                     }
11623                 }
11624             }
11625         }
11626
11627         if (!app.isolated) {
11628             // XXX Can't keep track of crash times for isolated processes,
11629             // because they don't have a perisistent identity.
11630             mProcessCrashTimes.put(app.info.processName, app.uid, now);
11631         }
11632
11633         if (app.crashHandler != null) mHandler.post(app.crashHandler);
11634         return true;
11635     }
11636
11637     void startAppProblemLocked(ProcessRecord app) {
11638         // If this app is not running under the current user, then we
11639         // can't give it a report button because that would require
11640         // launching the report UI under a different user.
11641         app.errorReportReceiver = null;
11642
11643         for (int userId : mCurrentProfileIds) {
11644             if (app.userId == userId) {
11645                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11646                         mContext, app.info.packageName, app.info.flags);
11647             }
11648         }
11649         skipCurrentReceiverLocked(app);
11650     }
11651
11652     void skipCurrentReceiverLocked(ProcessRecord app) {
11653         for (BroadcastQueue queue : mBroadcastQueues) {
11654             queue.skipCurrentReceiverLocked(app);
11655         }
11656     }
11657
11658     /**
11659      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11660      * The application process will exit immediately after this call returns.
11661      * @param app object of the crashing app, null for the system server
11662      * @param crashInfo describing the exception
11663      */
11664     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11665         ProcessRecord r = findAppProcess(app, "Crash");
11666         final String processName = app == null ? "system_server"
11667                 : (r == null ? "unknown" : r.processName);
11668
11669         handleApplicationCrashInner("crash", r, processName, crashInfo);
11670     }
11671
11672     /* Native crash reporting uses this inner version because it needs to be somewhat
11673      * decoupled from the AM-managed cleanup lifecycle
11674      */
11675     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11676             ApplicationErrorReport.CrashInfo crashInfo) {
11677         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11678                 UserHandle.getUserId(Binder.getCallingUid()), processName,
11679                 r == null ? -1 : r.info.flags,
11680                 crashInfo.exceptionClassName,
11681                 crashInfo.exceptionMessage,
11682                 crashInfo.throwFileName,
11683                 crashInfo.throwLineNumber);
11684
11685         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11686
11687         crashApplication(r, crashInfo);
11688     }
11689
11690     public void handleApplicationStrictModeViolation(
11691             IBinder app,
11692             int violationMask,
11693             StrictMode.ViolationInfo info) {
11694         ProcessRecord r = findAppProcess(app, "StrictMode");
11695         if (r == null) {
11696             return;
11697         }
11698
11699         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11700             Integer stackFingerprint = info.hashCode();
11701             boolean logIt = true;
11702             synchronized (mAlreadyLoggedViolatedStacks) {
11703                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11704                     logIt = false;
11705                     // TODO: sub-sample into EventLog for these, with
11706                     // the info.durationMillis?  Then we'd get
11707                     // the relative pain numbers, without logging all
11708                     // the stack traces repeatedly.  We'd want to do
11709                     // likewise in the client code, which also does
11710                     // dup suppression, before the Binder call.
11711                 } else {
11712                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11713                         mAlreadyLoggedViolatedStacks.clear();
11714                     }
11715                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11716                 }
11717             }
11718             if (logIt) {
11719                 logStrictModeViolationToDropBox(r, info);
11720             }
11721         }
11722
11723         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11724             AppErrorResult result = new AppErrorResult();
11725             synchronized (this) {
11726                 final long origId = Binder.clearCallingIdentity();
11727
11728                 Message msg = Message.obtain();
11729                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11730                 HashMap<String, Object> data = new HashMap<String, Object>();
11731                 data.put("result", result);
11732                 data.put("app", r);
11733                 data.put("violationMask", violationMask);
11734                 data.put("info", info);
11735                 msg.obj = data;
11736                 mUiHandler.sendMessage(msg);
11737
11738                 Binder.restoreCallingIdentity(origId);
11739             }
11740             int res = result.get();
11741             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11742         }
11743     }
11744
11745     // Depending on the policy in effect, there could be a bunch of
11746     // these in quick succession so we try to batch these together to
11747     // minimize disk writes, number of dropbox entries, and maximize
11748     // compression, by having more fewer, larger records.
11749     private void logStrictModeViolationToDropBox(
11750             ProcessRecord process,
11751             StrictMode.ViolationInfo info) {
11752         if (info == null) {
11753             return;
11754         }
11755         final boolean isSystemApp = process == null ||
11756                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11757                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11758         final String processName = process == null ? "unknown" : process.processName;
11759         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11760         final DropBoxManager dbox = (DropBoxManager)
11761                 mContext.getSystemService(Context.DROPBOX_SERVICE);
11762
11763         // Exit early if the dropbox isn't configured to accept this report type.
11764         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11765
11766         boolean bufferWasEmpty;
11767         boolean needsFlush;
11768         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11769         synchronized (sb) {
11770             bufferWasEmpty = sb.length() == 0;
11771             appendDropBoxProcessHeaders(process, processName, sb);
11772             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11773             sb.append("System-App: ").append(isSystemApp).append("\n");
11774             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11775             if (info.violationNumThisLoop != 0) {
11776                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11777             }
11778             if (info.numAnimationsRunning != 0) {
11779                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11780             }
11781             if (info.broadcastIntentAction != null) {
11782                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11783             }
11784             if (info.durationMillis != -1) {
11785                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11786             }
11787             if (info.numInstances != -1) {
11788                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11789             }
11790             if (info.tags != null) {
11791                 for (String tag : info.tags) {
11792                     sb.append("Span-Tag: ").append(tag).append("\n");
11793                 }
11794             }
11795             sb.append("\n");
11796             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11797                 sb.append(info.crashInfo.stackTrace);
11798                 sb.append("\n");
11799             }
11800             if (info.message != null) {
11801                 sb.append(info.message);
11802                 sb.append("\n");
11803             }
11804
11805             // Only buffer up to ~64k.  Various logging bits truncate
11806             // things at 128k.
11807             needsFlush = (sb.length() > 64 * 1024);
11808         }
11809
11810         // Flush immediately if the buffer's grown too large, or this
11811         // is a non-system app.  Non-system apps are isolated with a
11812         // different tag & policy and not batched.
11813         //
11814         // Batching is useful during internal testing with
11815         // StrictMode settings turned up high.  Without batching,
11816         // thousands of separate files could be created on boot.
11817         if (!isSystemApp || needsFlush) {
11818             new Thread("Error dump: " + dropboxTag) {
11819                 @Override
11820                 public void run() {
11821                     String report;
11822                     synchronized (sb) {
11823                         report = sb.toString();
11824                         sb.delete(0, sb.length());
11825                         sb.trimToSize();
11826                     }
11827                     if (report.length() != 0) {
11828                         dbox.addText(dropboxTag, report);
11829                     }
11830                 }
11831             }.start();
11832             return;
11833         }
11834
11835         // System app batching:
11836         if (!bufferWasEmpty) {
11837             // An existing dropbox-writing thread is outstanding, so
11838             // we don't need to start it up.  The existing thread will
11839             // catch the buffer appends we just did.
11840             return;
11841         }
11842
11843         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11844         // (After this point, we shouldn't access AMS internal data structures.)
11845         new Thread("Error dump: " + dropboxTag) {
11846             @Override
11847             public void run() {
11848                 // 5 second sleep to let stacks arrive and be batched together
11849                 try {
11850                     Thread.sleep(5000);  // 5 seconds
11851                 } catch (InterruptedException e) {}
11852
11853                 String errorReport;
11854                 synchronized (mStrictModeBuffer) {
11855                     errorReport = mStrictModeBuffer.toString();
11856                     if (errorReport.length() == 0) {
11857                         return;
11858                     }
11859                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11860                     mStrictModeBuffer.trimToSize();
11861                 }
11862                 dbox.addText(dropboxTag, errorReport);
11863             }
11864         }.start();
11865     }
11866
11867     /**
11868      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11869      * @param app object of the crashing app, null for the system server
11870      * @param tag reported by the caller
11871      * @param system whether this wtf is coming from the system
11872      * @param crashInfo describing the context of the error
11873      * @return true if the process should exit immediately (WTF is fatal)
11874      */
11875     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11876             final ApplicationErrorReport.CrashInfo crashInfo) {
11877         final int callingUid = Binder.getCallingUid();
11878         final int callingPid = Binder.getCallingPid();
11879
11880         if (system) {
11881             // If this is coming from the system, we could very well have low-level
11882             // system locks held, so we want to do this all asynchronously.  And we
11883             // never want this to become fatal, so there is that too.
11884             mHandler.post(new Runnable() {
11885                 @Override public void run() {
11886                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11887                 }
11888             });
11889             return false;
11890         }
11891
11892         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11893                 crashInfo);
11894
11895         if (r != null && r.pid != Process.myPid() &&
11896                 Settings.Global.getInt(mContext.getContentResolver(),
11897                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
11898             crashApplication(r, crashInfo);
11899             return true;
11900         } else {
11901             return false;
11902         }
11903     }
11904
11905     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11906             final ApplicationErrorReport.CrashInfo crashInfo) {
11907         final ProcessRecord r = findAppProcess(app, "WTF");
11908         final String processName = app == null ? "system_server"
11909                 : (r == null ? "unknown" : r.processName);
11910
11911         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11912                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11913
11914         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11915
11916         return r;
11917     }
11918
11919     /**
11920      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11921      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11922      */
11923     private ProcessRecord findAppProcess(IBinder app, String reason) {
11924         if (app == null) {
11925             return null;
11926         }
11927
11928         synchronized (this) {
11929             final int NP = mProcessNames.getMap().size();
11930             for (int ip=0; ip<NP; ip++) {
11931                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11932                 final int NA = apps.size();
11933                 for (int ia=0; ia<NA; ia++) {
11934                     ProcessRecord p = apps.valueAt(ia);
11935                     if (p.thread != null && p.thread.asBinder() == app) {
11936                         return p;
11937                     }
11938                 }
11939             }
11940
11941             Slog.w(TAG, "Can't find mystery application for " + reason
11942                     + " from pid=" + Binder.getCallingPid()
11943                     + " uid=" + Binder.getCallingUid() + ": " + app);
11944             return null;
11945         }
11946     }
11947
11948     /**
11949      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11950      * to append various headers to the dropbox log text.
11951      */
11952     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11953             StringBuilder sb) {
11954         // Watchdog thread ends up invoking this function (with
11955         // a null ProcessRecord) to add the stack file to dropbox.
11956         // Do not acquire a lock on this (am) in such cases, as it
11957         // could cause a potential deadlock, if and when watchdog
11958         // is invoked due to unavailability of lock on am and it
11959         // would prevent watchdog from killing system_server.
11960         if (process == null) {
11961             sb.append("Process: ").append(processName).append("\n");
11962             return;
11963         }
11964         // Note: ProcessRecord 'process' is guarded by the service
11965         // instance.  (notably process.pkgList, which could otherwise change
11966         // concurrently during execution of this method)
11967         synchronized (this) {
11968             sb.append("Process: ").append(processName).append("\n");
11969             int flags = process.info.flags;
11970             IPackageManager pm = AppGlobals.getPackageManager();
11971             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11972             for (int ip=0; ip<process.pkgList.size(); ip++) {
11973                 String pkg = process.pkgList.keyAt(ip);
11974                 sb.append("Package: ").append(pkg);
11975                 try {
11976                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11977                     if (pi != null) {
11978                         sb.append(" v").append(pi.versionCode);
11979                         if (pi.versionName != null) {
11980                             sb.append(" (").append(pi.versionName).append(")");
11981                         }
11982                     }
11983                 } catch (RemoteException e) {
11984                     Slog.e(TAG, "Error getting package info: " + pkg, e);
11985                 }
11986                 sb.append("\n");
11987             }
11988         }
11989     }
11990
11991     private static String processClass(ProcessRecord process) {
11992         if (process == null || process.pid == MY_PID) {
11993             return "system_server";
11994         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11995             return "system_app";
11996         } else {
11997             return "data_app";
11998         }
11999     }
12000
12001     /**
12002      * Write a description of an error (crash, WTF, ANR) to the drop box.
12003      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12004      * @param process which caused the error, null means the system server
12005      * @param activity which triggered the error, null if unknown
12006      * @param parent activity related to the error, null if unknown
12007      * @param subject line related to the error, null if absent
12008      * @param report in long form describing the error, null if absent
12009      * @param logFile to include in the report, null if none
12010      * @param crashInfo giving an application stack trace, null if absent
12011      */
12012     public void addErrorToDropBox(String eventType,
12013             ProcessRecord process, String processName, ActivityRecord activity,
12014             ActivityRecord parent, String subject,
12015             final String report, final File logFile,
12016             final ApplicationErrorReport.CrashInfo crashInfo) {
12017         // NOTE -- this must never acquire the ActivityManagerService lock,
12018         // otherwise the watchdog may be prevented from resetting the system.
12019
12020         final String dropboxTag = processClass(process) + "_" + eventType;
12021         final DropBoxManager dbox = (DropBoxManager)
12022                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12023
12024         // Exit early if the dropbox isn't configured to accept this report type.
12025         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12026
12027         final StringBuilder sb = new StringBuilder(1024);
12028         appendDropBoxProcessHeaders(process, processName, sb);
12029         if (activity != null) {
12030             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12031         }
12032         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12033             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12034         }
12035         if (parent != null && parent != activity) {
12036             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12037         }
12038         if (subject != null) {
12039             sb.append("Subject: ").append(subject).append("\n");
12040         }
12041         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12042         if (Debug.isDebuggerConnected()) {
12043             sb.append("Debugger: Connected\n");
12044         }
12045         sb.append("\n");
12046
12047         // Do the rest in a worker thread to avoid blocking the caller on I/O
12048         // (After this point, we shouldn't access AMS internal data structures.)
12049         Thread worker = new Thread("Error dump: " + dropboxTag) {
12050             @Override
12051             public void run() {
12052                 if (report != null) {
12053                     sb.append(report);
12054                 }
12055                 if (logFile != null) {
12056                     try {
12057                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12058                                     "\n\n[[TRUNCATED]]"));
12059                     } catch (IOException e) {
12060                         Slog.e(TAG, "Error reading " + logFile, e);
12061                     }
12062                 }
12063                 if (crashInfo != null && crashInfo.stackTrace != null) {
12064                     sb.append(crashInfo.stackTrace);
12065                 }
12066
12067                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12068                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12069                 if (lines > 0) {
12070                     sb.append("\n");
12071
12072                     // Merge several logcat streams, and take the last N lines
12073                     InputStreamReader input = null;
12074                     try {
12075                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12076                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12077                                 "-b", "crash",
12078                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12079
12080                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12081                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12082                         input = new InputStreamReader(logcat.getInputStream());
12083
12084                         int num;
12085                         char[] buf = new char[8192];
12086                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12087                     } catch (IOException e) {
12088                         Slog.e(TAG, "Error running logcat", e);
12089                     } finally {
12090                         if (input != null) try { input.close(); } catch (IOException e) {}
12091                     }
12092                 }
12093
12094                 dbox.addText(dropboxTag, sb.toString());
12095             }
12096         };
12097
12098         if (process == null) {
12099             // If process is null, we are being called from some internal code
12100             // and may be about to die -- run this synchronously.
12101             worker.run();
12102         } else {
12103             worker.start();
12104         }
12105     }
12106
12107     /**
12108      * Bring up the "unexpected error" dialog box for a crashing app.
12109      * Deal with edge cases (intercepts from instrumented applications,
12110      * ActivityController, error intent receivers, that sort of thing).
12111      * @param r the application crashing
12112      * @param crashInfo describing the failure
12113      */
12114     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12115         long timeMillis = System.currentTimeMillis();
12116         String shortMsg = crashInfo.exceptionClassName;
12117         String longMsg = crashInfo.exceptionMessage;
12118         String stackTrace = crashInfo.stackTrace;
12119         if (shortMsg != null && longMsg != null) {
12120             longMsg = shortMsg + ": " + longMsg;
12121         } else if (shortMsg != null) {
12122             longMsg = shortMsg;
12123         }
12124
12125         AppErrorResult result = new AppErrorResult();
12126         synchronized (this) {
12127             if (mController != null) {
12128                 try {
12129                     String name = r != null ? r.processName : null;
12130                     int pid = r != null ? r.pid : Binder.getCallingPid();
12131                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12132                     if (!mController.appCrashed(name, pid,
12133                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12134                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12135                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12136                             Slog.w(TAG, "Skip killing native crashed app " + name
12137                                     + "(" + pid + ") during testing");
12138                         } else {
12139                             Slog.w(TAG, "Force-killing crashed app " + name
12140                                     + " at watcher's request");
12141                             if (r != null) {
12142                                 r.kill("crash", true);
12143                             } else {
12144                                 // Huh.
12145                                 Process.killProcess(pid);
12146                                 Process.killProcessGroup(uid, pid);
12147                             }
12148                         }
12149                         return;
12150                     }
12151                 } catch (RemoteException e) {
12152                     mController = null;
12153                     Watchdog.getInstance().setActivityController(null);
12154                 }
12155             }
12156
12157             final long origId = Binder.clearCallingIdentity();
12158
12159             // If this process is running instrumentation, finish it.
12160             if (r != null && r.instrumentationClass != null) {
12161                 Slog.w(TAG, "Error in app " + r.processName
12162                       + " running instrumentation " + r.instrumentationClass + ":");
12163                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12164                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12165                 Bundle info = new Bundle();
12166                 info.putString("shortMsg", shortMsg);
12167                 info.putString("longMsg", longMsg);
12168                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12169                 Binder.restoreCallingIdentity(origId);
12170                 return;
12171             }
12172
12173             // Log crash in battery stats.
12174             if (r != null) {
12175                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12176             }
12177
12178             // If we can't identify the process or it's already exceeded its crash quota,
12179             // quit right away without showing a crash dialog.
12180             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12181                 Binder.restoreCallingIdentity(origId);
12182                 return;
12183             }
12184
12185             Message msg = Message.obtain();
12186             msg.what = SHOW_ERROR_MSG;
12187             HashMap data = new HashMap();
12188             data.put("result", result);
12189             data.put("app", r);
12190             msg.obj = data;
12191             mUiHandler.sendMessage(msg);
12192
12193             Binder.restoreCallingIdentity(origId);
12194         }
12195
12196         int res = result.get();
12197
12198         Intent appErrorIntent = null;
12199         synchronized (this) {
12200             if (r != null && !r.isolated) {
12201                 // XXX Can't keep track of crash time for isolated processes,
12202                 // since they don't have a persistent identity.
12203                 mProcessCrashTimes.put(r.info.processName, r.uid,
12204                         SystemClock.uptimeMillis());
12205             }
12206             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12207                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12208             }
12209         }
12210
12211         if (appErrorIntent != null) {
12212             try {
12213                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12214             } catch (ActivityNotFoundException e) {
12215                 Slog.w(TAG, "bug report receiver dissappeared", e);
12216             }
12217         }
12218     }
12219
12220     Intent createAppErrorIntentLocked(ProcessRecord r,
12221             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12222         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12223         if (report == null) {
12224             return null;
12225         }
12226         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12227         result.setComponent(r.errorReportReceiver);
12228         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12229         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12230         return result;
12231     }
12232
12233     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12234             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12235         if (r.errorReportReceiver == null) {
12236             return null;
12237         }
12238
12239         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12240             return null;
12241         }
12242
12243         ApplicationErrorReport report = new ApplicationErrorReport();
12244         report.packageName = r.info.packageName;
12245         report.installerPackageName = r.errorReportReceiver.getPackageName();
12246         report.processName = r.processName;
12247         report.time = timeMillis;
12248         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12249
12250         if (r.crashing || r.forceCrashReport) {
12251             report.type = ApplicationErrorReport.TYPE_CRASH;
12252             report.crashInfo = crashInfo;
12253         } else if (r.notResponding) {
12254             report.type = ApplicationErrorReport.TYPE_ANR;
12255             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12256
12257             report.anrInfo.activity = r.notRespondingReport.tag;
12258             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12259             report.anrInfo.info = r.notRespondingReport.longMsg;
12260         }
12261
12262         return report;
12263     }
12264
12265     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12266         enforceNotIsolatedCaller("getProcessesInErrorState");
12267         // assume our apps are happy - lazy create the list
12268         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12269
12270         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12271                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12272         int userId = UserHandle.getUserId(Binder.getCallingUid());
12273
12274         synchronized (this) {
12275
12276             // iterate across all processes
12277             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12278                 ProcessRecord app = mLruProcesses.get(i);
12279                 if (!allUsers && app.userId != userId) {
12280                     continue;
12281                 }
12282                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12283                     // This one's in trouble, so we'll generate a report for it
12284                     // crashes are higher priority (in case there's a crash *and* an anr)
12285                     ActivityManager.ProcessErrorStateInfo report = null;
12286                     if (app.crashing) {
12287                         report = app.crashingReport;
12288                     } else if (app.notResponding) {
12289                         report = app.notRespondingReport;
12290                     }
12291                     
12292                     if (report != null) {
12293                         if (errList == null) {
12294                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12295                         }
12296                         errList.add(report);
12297                     } else {
12298                         Slog.w(TAG, "Missing app error report, app = " + app.processName + 
12299                                 " crashing = " + app.crashing +
12300                                 " notResponding = " + app.notResponding);
12301                     }
12302                 }
12303             }
12304         }
12305
12306         return errList;
12307     }
12308
12309     static int procStateToImportance(int procState, int memAdj,
12310             ActivityManager.RunningAppProcessInfo currApp) {
12311         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12312         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12313             currApp.lru = memAdj;
12314         } else {
12315             currApp.lru = 0;
12316         }
12317         return imp;
12318     }
12319
12320     private void fillInProcMemInfo(ProcessRecord app,
12321             ActivityManager.RunningAppProcessInfo outInfo) {
12322         outInfo.pid = app.pid;
12323         outInfo.uid = app.info.uid;
12324         if (mHeavyWeightProcess == app) {
12325             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12326         }
12327         if (app.persistent) {
12328             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12329         }
12330         if (app.activities.size() > 0) {
12331             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12332         }
12333         outInfo.lastTrimLevel = app.trimMemoryLevel;
12334         int adj = app.curAdj;
12335         int procState = app.curProcState;
12336         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12337         outInfo.importanceReasonCode = app.adjTypeCode;
12338         outInfo.processState = app.curProcState;
12339     }
12340
12341     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12342         enforceNotIsolatedCaller("getRunningAppProcesses");
12343
12344         final int callingUid = Binder.getCallingUid();
12345
12346         // Lazy instantiation of list
12347         List<ActivityManager.RunningAppProcessInfo> runList = null;
12348         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12349                 callingUid) == PackageManager.PERMISSION_GRANTED;
12350         final int userId = UserHandle.getUserId(callingUid);
12351         final boolean allUids = isGetTasksAllowed(
12352                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12353
12354         synchronized (this) {
12355             // Iterate across all processes
12356             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12357                 ProcessRecord app = mLruProcesses.get(i);
12358                 if ((!allUsers && app.userId != userId)
12359                         || (!allUids && app.uid != callingUid)) {
12360                     continue;
12361                 }
12362                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12363                     // Generate process state info for running application
12364                     ActivityManager.RunningAppProcessInfo currApp = 
12365                         new ActivityManager.RunningAppProcessInfo(app.processName,
12366                                 app.pid, app.getPackageList());
12367                     fillInProcMemInfo(app, currApp);
12368                     if (app.adjSource instanceof ProcessRecord) {
12369                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12370                         currApp.importanceReasonImportance =
12371                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12372                                         app.adjSourceProcState);
12373                     } else if (app.adjSource instanceof ActivityRecord) {
12374                         ActivityRecord r = (ActivityRecord)app.adjSource;
12375                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12376                     }
12377                     if (app.adjTarget instanceof ComponentName) {
12378                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12379                     }
12380                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12381                     //        + " lru=" + currApp.lru);
12382                     if (runList == null) {
12383                         runList = new ArrayList<>();
12384                     }
12385                     runList.add(currApp);
12386                 }
12387             }
12388         }
12389         return runList;
12390     }
12391
12392     public List<ApplicationInfo> getRunningExternalApplications() {
12393         enforceNotIsolatedCaller("getRunningExternalApplications");
12394         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12395         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12396         if (runningApps != null && runningApps.size() > 0) {
12397             Set<String> extList = new HashSet<String>();
12398             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12399                 if (app.pkgList != null) {
12400                     for (String pkg : app.pkgList) {
12401                         extList.add(pkg);
12402                     }
12403                 }
12404             }
12405             IPackageManager pm = AppGlobals.getPackageManager();
12406             for (String pkg : extList) {
12407                 try {
12408                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12409                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12410                         retList.add(info);
12411                     }
12412                 } catch (RemoteException e) {
12413                 }
12414             }
12415         }
12416         return retList;
12417     }
12418
12419     @Override
12420     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12421         enforceNotIsolatedCaller("getMyMemoryState");
12422         synchronized (this) {
12423             ProcessRecord proc;
12424             synchronized (mPidsSelfLocked) {
12425                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12426             }
12427             fillInProcMemInfo(proc, outInfo);
12428         }
12429     }
12430
12431     @Override
12432     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12433         if (checkCallingPermission(android.Manifest.permission.DUMP)
12434                 != PackageManager.PERMISSION_GRANTED) {
12435             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12436                     + Binder.getCallingPid()
12437                     + ", uid=" + Binder.getCallingUid()
12438                     + " without permission "
12439                     + android.Manifest.permission.DUMP);
12440             return;
12441         }
12442
12443         boolean dumpAll = false;
12444         boolean dumpClient = false;
12445         String dumpPackage = null;
12446         
12447         int opti = 0;
12448         while (opti < args.length) {
12449             String opt = args[opti];
12450             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12451                 break;
12452             }
12453             opti++;
12454             if ("-a".equals(opt)) {
12455                 dumpAll = true;
12456             } else if ("-c".equals(opt)) {
12457                 dumpClient = true;
12458             } else if ("-p".equals(opt)) {
12459                 if (opti < args.length) {
12460                     dumpPackage = args[opti];
12461                     opti++;
12462                 } else {
12463                     pw.println("Error: -p option requires package argument");
12464                     return;
12465                 }
12466                 dumpClient = true;
12467             } else if ("-h".equals(opt)) {
12468                 pw.println("Activity manager dump options:");
12469                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12470                 pw.println("  cmd may be one of:");
12471                 pw.println("    a[ctivities]: activity stack state");
12472                 pw.println("    r[recents]: recent activities state");
12473                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12474                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12475                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12476                 pw.println("    o[om]: out of memory management");
12477                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12478                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12479                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12480                 pw.println("    as[sociations]: tracked app associations");
12481                 pw.println("    service [COMP_SPEC]: service client-side state");
12482                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12483                 pw.println("    all: dump all activities");
12484                 pw.println("    top: dump the top activity");
12485                 pw.println("    write: write all pending state to storage");
12486                 pw.println("    track-associations: enable association tracking");
12487                 pw.println("    untrack-associations: disable and clear association tracking");
12488                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12489                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12490                 pw.println("    a partial substring in a component name, a");
12491                 pw.println("    hex object identifier.");
12492                 pw.println("  -a: include all available server state.");
12493                 pw.println("  -c: include client state.");
12494                 pw.println("  -p: limit output to given package.");
12495                 return;
12496             } else {
12497                 pw.println("Unknown argument: " + opt + "; use -h for help");
12498             }
12499         }
12500
12501         long origId = Binder.clearCallingIdentity();
12502         boolean more = false;
12503         // Is the caller requesting to dump a particular piece of data?
12504         if (opti < args.length) {
12505             String cmd = args[opti];
12506             opti++;
12507             if ("activities".equals(cmd) || "a".equals(cmd)) {
12508                 synchronized (this) {
12509                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12510                 }
12511             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12512                 synchronized (this) {
12513                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12514                 }
12515             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12516                 String[] newArgs;
12517                 String name;
12518                 if (opti >= args.length) {
12519                     name = null;
12520                     newArgs = EMPTY_STRING_ARRAY;
12521                 } else {
12522                     dumpPackage = args[opti];
12523                     opti++;
12524                     newArgs = new String[args.length - opti];
12525                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12526                             args.length - opti);
12527                 }
12528                 synchronized (this) {
12529                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12530                 }
12531             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12532                 String[] newArgs;
12533                 String name;
12534                 if (opti >= args.length) {
12535                     name = null;
12536                     newArgs = EMPTY_STRING_ARRAY;
12537                 } else {
12538                     dumpPackage = args[opti];
12539                     opti++;
12540                     newArgs = new String[args.length - opti];
12541                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12542                             args.length - opti);
12543                 }
12544                 synchronized (this) {
12545                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12546                 }
12547             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12548                 String[] newArgs;
12549                 String name;
12550                 if (opti >= args.length) {
12551                     name = null;
12552                     newArgs = EMPTY_STRING_ARRAY;
12553                 } else {
12554                     dumpPackage = args[opti];
12555                     opti++;
12556                     newArgs = new String[args.length - opti];
12557                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12558                             args.length - opti);
12559                 }
12560                 synchronized (this) {
12561                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12562                 }
12563             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12564                 synchronized (this) {
12565                     dumpOomLocked(fd, pw, args, opti, true);
12566                 }
12567             } else if ("provider".equals(cmd)) {
12568                 String[] newArgs;
12569                 String name;
12570                 if (opti >= args.length) {
12571                     name = null;
12572                     newArgs = EMPTY_STRING_ARRAY;
12573                 } else {
12574                     name = args[opti];
12575                     opti++;
12576                     newArgs = new String[args.length - opti];
12577                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12578                 }
12579                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12580                     pw.println("No providers match: " + name);
12581                     pw.println("Use -h for help.");
12582                 }
12583             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12584                 synchronized (this) {
12585                     dumpProvidersLocked(fd, pw, args, opti, true, null);
12586                 }
12587             } else if ("service".equals(cmd)) {
12588                 String[] newArgs;
12589                 String name;
12590                 if (opti >= args.length) {
12591                     name = null;
12592                     newArgs = EMPTY_STRING_ARRAY;
12593                 } else {
12594                     name = args[opti];
12595                     opti++;
12596                     newArgs = new String[args.length - opti];
12597                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12598                             args.length - opti);
12599                 }
12600                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12601                     pw.println("No services match: " + name);
12602                     pw.println("Use -h for help.");
12603                 }
12604             } else if ("package".equals(cmd)) {
12605                 String[] newArgs;
12606                 if (opti >= args.length) {
12607                     pw.println("package: no package name specified");
12608                     pw.println("Use -h for help.");
12609                 } else {
12610                     dumpPackage = args[opti];
12611                     opti++;
12612                     newArgs = new String[args.length - opti];
12613                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12614                             args.length - opti);
12615                     args = newArgs;
12616                     opti = 0;
12617                     more = true;
12618                 }
12619             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12620                 synchronized (this) {
12621                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12622                 }
12623             } else if ("services".equals(cmd) || "s".equals(cmd)) {
12624                 synchronized (this) {
12625                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12626                 }
12627             } else if ("write".equals(cmd)) {
12628                 mTaskPersister.flush();
12629                 pw.println("All tasks persisted.");
12630                 return;
12631             } else if ("track-associations".equals(cmd)) {
12632                 synchronized (this) {
12633                     if (!mTrackingAssociations) {
12634                         mTrackingAssociations = true;
12635                         pw.println("Association tracking started.");
12636                     } else {
12637                         pw.println("Association tracking already enabled.");
12638                     }
12639                 }
12640                 return;
12641             } else if ("untrack-associations".equals(cmd)) {
12642                 synchronized (this) {
12643                     if (mTrackingAssociations) {
12644                         mTrackingAssociations = false;
12645                         mAssociations.clear();
12646                         pw.println("Association tracking stopped.");
12647                     } else {
12648                         pw.println("Association tracking not running.");
12649                     }
12650                 }
12651                 return;
12652             } else {
12653                 // Dumping a single activity?
12654                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12655                     pw.println("Bad activity command, or no activities match: " + cmd);
12656                     pw.println("Use -h for help.");
12657                 }
12658             }
12659             if (!more) {
12660                 Binder.restoreCallingIdentity(origId);
12661                 return;
12662             }
12663         }
12664
12665         // No piece of data specified, dump everything.
12666         synchronized (this) {
12667             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12668             pw.println();
12669             if (dumpAll) {
12670                 pw.println("-------------------------------------------------------------------------------");
12671             }
12672             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12673             pw.println();
12674             if (dumpAll) {
12675                 pw.println("-------------------------------------------------------------------------------");
12676             }
12677             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12678             pw.println();
12679             if (dumpAll) {
12680                 pw.println("-------------------------------------------------------------------------------");
12681             }
12682             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12683             pw.println();
12684             if (dumpAll) {
12685                 pw.println("-------------------------------------------------------------------------------");
12686             }
12687             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12688             pw.println();
12689             if (dumpAll) {
12690                 pw.println("-------------------------------------------------------------------------------");
12691             }
12692             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12693             if (mAssociations.size() > 0) {
12694                 pw.println();
12695                 if (dumpAll) {
12696                     pw.println("-------------------------------------------------------------------------------");
12697                 }
12698                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12699             }
12700             pw.println();
12701             if (dumpAll) {
12702                 pw.println("-------------------------------------------------------------------------------");
12703             }
12704             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12705         }
12706         Binder.restoreCallingIdentity(origId);
12707     }
12708
12709     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12710             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12711         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12712
12713         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12714                 dumpPackage);
12715         boolean needSep = printedAnything;
12716
12717         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12718                 dumpPackage, needSep, "  mFocusedActivity: ");
12719         if (printed) {
12720             printedAnything = true;
12721             needSep = false;
12722         }
12723
12724         if (dumpPackage == null) {
12725             if (needSep) {
12726                 pw.println();
12727             }
12728             needSep = true;
12729             printedAnything = true;
12730             mStackSupervisor.dump(pw, "  ");
12731         }
12732
12733         if (!printedAnything) {
12734             pw.println("  (nothing)");
12735         }
12736     }
12737
12738     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12739             int opti, boolean dumpAll, String dumpPackage) {
12740         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12741
12742         boolean printedAnything = false;
12743
12744         if (mRecentTasks != null && mRecentTasks.size() > 0) {
12745             boolean printedHeader = false;
12746
12747             final int N = mRecentTasks.size();
12748             for (int i=0; i<N; i++) {
12749                 TaskRecord tr = mRecentTasks.get(i);
12750                 if (dumpPackage != null) {
12751                     if (tr.realActivity == null ||
12752                             !dumpPackage.equals(tr.realActivity)) {
12753                         continue;
12754                     }
12755                 }
12756                 if (!printedHeader) {
12757                     pw.println("  Recent tasks:");
12758                     printedHeader = true;
12759                     printedAnything = true;
12760                 }
12761                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12762                         pw.println(tr);
12763                 if (dumpAll) {
12764                     mRecentTasks.get(i).dump(pw, "    ");
12765                 }
12766             }
12767         }
12768
12769         if (!printedAnything) {
12770             pw.println("  (nothing)");
12771         }
12772     }
12773
12774     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12775             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12776         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12777
12778         int dumpUid = 0;
12779         if (dumpPackage != null) {
12780             IPackageManager pm = AppGlobals.getPackageManager();
12781             try {
12782                 dumpUid = pm.getPackageUid(dumpPackage, 0);
12783             } catch (RemoteException e) {
12784             }
12785         }
12786
12787         boolean printedAnything = false;
12788
12789         final long now = SystemClock.uptimeMillis();
12790
12791         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12792             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12793                     = mAssociations.valueAt(i1);
12794             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12795                 SparseArray<ArrayMap<String, Association>> sourceUids
12796                         = targetComponents.valueAt(i2);
12797                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12798                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12799                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12800                         Association ass = sourceProcesses.valueAt(i4);
12801                         if (dumpPackage != null) {
12802                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12803                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12804                                 continue;
12805                             }
12806                         }
12807                         printedAnything = true;
12808                         pw.print("  ");
12809                         pw.print(ass.mTargetProcess);
12810                         pw.print("/");
12811                         UserHandle.formatUid(pw, ass.mTargetUid);
12812                         pw.print(" <- ");
12813                         pw.print(ass.mSourceProcess);
12814                         pw.print("/");
12815                         UserHandle.formatUid(pw, ass.mSourceUid);
12816                         pw.println();
12817                         pw.print("    via ");
12818                         pw.print(ass.mTargetComponent.flattenToShortString());
12819                         pw.println();
12820                         pw.print("    ");
12821                         long dur = ass.mTime;
12822                         if (ass.mNesting > 0) {
12823                             dur += now - ass.mStartTime;
12824                         }
12825                         TimeUtils.formatDuration(dur, pw);
12826                         pw.print(" (");
12827                         pw.print(ass.mCount);
12828                         pw.println(" times)");
12829                         if (ass.mNesting > 0) {
12830                             pw.print("    ");
12831                             pw.print(" Currently active: ");
12832                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
12833                             pw.println();
12834                         }
12835                     }
12836                 }
12837             }
12838
12839         }
12840
12841         if (!printedAnything) {
12842             pw.println("  (nothing)");
12843         }
12844     }
12845
12846     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12847             int opti, boolean dumpAll, String dumpPackage) {
12848         boolean needSep = false;
12849         boolean printedAnything = false;
12850         int numPers = 0;
12851
12852         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12853
12854         if (dumpAll) {
12855             final int NP = mProcessNames.getMap().size();
12856             for (int ip=0; ip<NP; ip++) {
12857                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12858                 final int NA = procs.size();
12859                 for (int ia=0; ia<NA; ia++) {
12860                     ProcessRecord r = procs.valueAt(ia);
12861                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12862                         continue;
12863                     }
12864                     if (!needSep) {
12865                         pw.println("  All known processes:");
12866                         needSep = true;
12867                         printedAnything = true;
12868                     }
12869                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12870                         pw.print(" UID "); pw.print(procs.keyAt(ia));
12871                         pw.print(" "); pw.println(r);
12872                     r.dump(pw, "    ");
12873                     if (r.persistent) {
12874                         numPers++;
12875                     }
12876                 }
12877             }
12878         }
12879
12880         if (mIsolatedProcesses.size() > 0) {
12881             boolean printed = false;
12882             for (int i=0; i<mIsolatedProcesses.size(); i++) {
12883                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12884                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12885                     continue;
12886                 }
12887                 if (!printed) {
12888                     if (needSep) {
12889                         pw.println();
12890                     }
12891                     pw.println("  Isolated process list (sorted by uid):");
12892                     printedAnything = true;
12893                     printed = true;
12894                     needSep = true;
12895                 }
12896                 pw.println(String.format("%sIsolated #%2d: %s",
12897                         "    ", i, r.toString()));
12898             }
12899         }
12900
12901         if (mLruProcesses.size() > 0) {
12902             if (needSep) {
12903                 pw.println();
12904             }
12905             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12906                     pw.print(" total, non-act at ");
12907                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12908                     pw.print(", non-svc at ");
12909                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12910                     pw.println("):");
12911             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12912             needSep = true;
12913             printedAnything = true;
12914         }
12915
12916         if (dumpAll || dumpPackage != null) {
12917             synchronized (mPidsSelfLocked) {
12918                 boolean printed = false;
12919                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12920                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
12921                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12922                         continue;
12923                     }
12924                     if (!printed) {
12925                         if (needSep) pw.println();
12926                         needSep = true;
12927                         pw.println("  PID mappings:");
12928                         printed = true;
12929                         printedAnything = true;
12930                     }
12931                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12932                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12933                 }
12934             }
12935         }
12936         
12937         if (mForegroundProcesses.size() > 0) {
12938             synchronized (mPidsSelfLocked) {
12939                 boolean printed = false;
12940                 for (int i=0; i<mForegroundProcesses.size(); i++) {
12941                     ProcessRecord r = mPidsSelfLocked.get( 
12942                             mForegroundProcesses.valueAt(i).pid);
12943                     if (dumpPackage != null && (r == null
12944                             || !r.pkgList.containsKey(dumpPackage))) {
12945                         continue;
12946                     }
12947                     if (!printed) {
12948                         if (needSep) pw.println();
12949                         needSep = true;
12950                         pw.println("  Foreground Processes:");
12951                         printed = true;
12952                         printedAnything = true;
12953                     }
12954                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12955                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12956                 }
12957             }
12958         }
12959         
12960         if (mPersistentStartingProcesses.size() > 0) {
12961             if (needSep) pw.println();
12962             needSep = true;
12963             printedAnything = true;
12964             pw.println("  Persisent processes that are starting:");
12965             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12966                     "Starting Norm", "Restarting PERS", dumpPackage);
12967         }
12968
12969         if (mRemovedProcesses.size() > 0) {
12970             if (needSep) pw.println();
12971             needSep = true;
12972             printedAnything = true;
12973             pw.println("  Processes that are being removed:");
12974             dumpProcessList(pw, this, mRemovedProcesses, "    ",
12975                     "Removed Norm", "Removed PERS", dumpPackage);
12976         }
12977         
12978         if (mProcessesOnHold.size() > 0) {
12979             if (needSep) pw.println();
12980             needSep = true;
12981             printedAnything = true;
12982             pw.println("  Processes that are on old until the system is ready:");
12983             dumpProcessList(pw, this, mProcessesOnHold, "    ",
12984                     "OnHold Norm", "OnHold PERS", dumpPackage);
12985         }
12986
12987         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12988         
12989         if (mProcessCrashTimes.getMap().size() > 0) {
12990             boolean printed = false;
12991             long now = SystemClock.uptimeMillis();
12992             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12993             final int NP = pmap.size();
12994             for (int ip=0; ip<NP; ip++) {
12995                 String pname = pmap.keyAt(ip);
12996                 SparseArray<Long> uids = pmap.valueAt(ip);
12997                 final int N = uids.size();
12998                 for (int i=0; i<N; i++) {
12999                     int puid = uids.keyAt(i);
13000                     ProcessRecord r = mProcessNames.get(pname, puid);
13001                     if (dumpPackage != null && (r == null
13002                             || !r.pkgList.containsKey(dumpPackage))) {
13003                         continue;
13004                     }
13005                     if (!printed) {
13006                         if (needSep) pw.println();
13007                         needSep = true;
13008                         pw.println("  Time since processes crashed:");
13009                         printed = true;
13010                         printedAnything = true;
13011                     }
13012                     pw.print("    Process "); pw.print(pname);
13013                             pw.print(" uid "); pw.print(puid);
13014                             pw.print(": last crashed ");
13015                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13016                             pw.println(" ago");
13017                 }
13018             }
13019         }
13020
13021         if (mBadProcesses.getMap().size() > 0) {
13022             boolean printed = false;
13023             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13024             final int NP = pmap.size();
13025             for (int ip=0; ip<NP; ip++) {
13026                 String pname = pmap.keyAt(ip);
13027                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13028                 final int N = uids.size();
13029                 for (int i=0; i<N; i++) {
13030                     int puid = uids.keyAt(i);
13031                     ProcessRecord r = mProcessNames.get(pname, puid);
13032                     if (dumpPackage != null && (r == null
13033                             || !r.pkgList.containsKey(dumpPackage))) {
13034                         continue;
13035                     }
13036                     if (!printed) {
13037                         if (needSep) pw.println();
13038                         needSep = true;
13039                         pw.println("  Bad processes:");
13040                         printedAnything = true;
13041                     }
13042                     BadProcessInfo info = uids.valueAt(i);
13043                     pw.print("    Bad process "); pw.print(pname);
13044                             pw.print(" uid "); pw.print(puid);
13045                             pw.print(": crashed at time "); pw.println(info.time);
13046                     if (info.shortMsg != null) {
13047                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13048                     }
13049                     if (info.longMsg != null) {
13050                         pw.print("      Long msg: "); pw.println(info.longMsg);
13051                     }
13052                     if (info.stack != null) {
13053                         pw.println("      Stack:");
13054                         int lastPos = 0;
13055                         for (int pos=0; pos<info.stack.length(); pos++) {
13056                             if (info.stack.charAt(pos) == '\n') {
13057                                 pw.print("        ");
13058                                 pw.write(info.stack, lastPos, pos-lastPos);
13059                                 pw.println();
13060                                 lastPos = pos+1;
13061                             }
13062                         }
13063                         if (lastPos < info.stack.length()) {
13064                             pw.print("        ");
13065                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13066                             pw.println();
13067                         }
13068                     }
13069                 }
13070             }
13071         }
13072
13073         if (dumpPackage == null) {
13074             pw.println();
13075             needSep = false;
13076             pw.println("  mStartedUsers:");
13077             for (int i=0; i<mStartedUsers.size(); i++) {
13078                 UserStartedState uss = mStartedUsers.valueAt(i);
13079                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13080                         pw.print(": "); uss.dump("", pw);
13081             }
13082             pw.print("  mStartedUserArray: [");
13083             for (int i=0; i<mStartedUserArray.length; i++) {
13084                 if (i > 0) pw.print(", ");
13085                 pw.print(mStartedUserArray[i]);
13086             }
13087             pw.println("]");
13088             pw.print("  mUserLru: [");
13089             for (int i=0; i<mUserLru.size(); i++) {
13090                 if (i > 0) pw.print(", ");
13091                 pw.print(mUserLru.get(i));
13092             }
13093             pw.println("]");
13094             if (dumpAll) {
13095                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13096             }
13097             synchronized (mUserProfileGroupIdsSelfLocked) {
13098                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13099                     pw.println("  mUserProfileGroupIds:");
13100                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13101                         pw.print("    User #");
13102                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13103                         pw.print(" -> profile #");
13104                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13105                     }
13106                 }
13107             }
13108         }
13109         if (mHomeProcess != null && (dumpPackage == null
13110                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13111             if (needSep) {
13112                 pw.println();
13113                 needSep = false;
13114             }
13115             pw.println("  mHomeProcess: " + mHomeProcess);
13116         }
13117         if (mPreviousProcess != null && (dumpPackage == null
13118                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13119             if (needSep) {
13120                 pw.println();
13121                 needSep = false;
13122             }
13123             pw.println("  mPreviousProcess: " + mPreviousProcess);
13124         }
13125         if (dumpAll) {
13126             StringBuilder sb = new StringBuilder(128);
13127             sb.append("  mPreviousProcessVisibleTime: ");
13128             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13129             pw.println(sb);
13130         }
13131         if (mHeavyWeightProcess != null && (dumpPackage == null
13132                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13133             if (needSep) {
13134                 pw.println();
13135                 needSep = false;
13136             }
13137             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13138         }
13139         if (dumpPackage == null) {
13140             pw.println("  mConfiguration: " + mConfiguration);
13141         }
13142         if (dumpAll) {
13143             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13144             if (mCompatModePackages.getPackages().size() > 0) {
13145                 boolean printed = false;
13146                 for (Map.Entry<String, Integer> entry
13147                         : mCompatModePackages.getPackages().entrySet()) {
13148                     String pkg = entry.getKey();
13149                     int mode = entry.getValue();
13150                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13151                         continue;
13152                     }
13153                     if (!printed) {
13154                         pw.println("  mScreenCompatPackages:");
13155                         printed = true;
13156                     }
13157                     pw.print("    "); pw.print(pkg); pw.print(": ");
13158                             pw.print(mode); pw.println();
13159                 }
13160             }
13161         }
13162         if (dumpPackage == null) {
13163             pw.println("  mWakefulness="
13164                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13165             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13166                     + lockScreenShownToString());
13167             pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13168                     + " mTestPssMode=" + mTestPssMode);
13169         }
13170         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13171                 || mOrigWaitForDebugger) {
13172             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13173                     || dumpPackage.equals(mOrigDebugApp)) {
13174                 if (needSep) {
13175                     pw.println();
13176                     needSep = false;
13177                 }
13178                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13179                         + " mDebugTransient=" + mDebugTransient
13180                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13181             }
13182         }
13183         if (mOpenGlTraceApp != null) {
13184             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13185                 if (needSep) {
13186                     pw.println();
13187                     needSep = false;
13188                 }
13189                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13190             }
13191         }
13192         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13193                 || mProfileFd != null) {
13194             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13195                 if (needSep) {
13196                     pw.println();
13197                     needSep = false;
13198                 }
13199                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13200                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13201                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13202                         + mAutoStopProfiler);
13203                 pw.println("  mProfileType=" + mProfileType);
13204             }
13205         }
13206         if (dumpPackage == null) {
13207             if (mAlwaysFinishActivities || mController != null) {
13208                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13209                         + " mController=" + mController);
13210             }
13211             if (dumpAll) {
13212                 pw.println("  Total persistent processes: " + numPers);
13213                 pw.println("  mProcessesReady=" + mProcessesReady
13214                         + " mSystemReady=" + mSystemReady
13215                         + " mBooted=" + mBooted
13216                         + " mFactoryTest=" + mFactoryTest);
13217                 pw.println("  mBooting=" + mBooting
13218                         + " mCallFinishBooting=" + mCallFinishBooting
13219                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13220                 pw.print("  mLastPowerCheckRealtime=");
13221                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13222                         pw.println("");
13223                 pw.print("  mLastPowerCheckUptime=");
13224                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13225                         pw.println("");
13226                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13227                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13228                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13229                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13230                         + " (" + mLruProcesses.size() + " total)"
13231                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13232                         + " mNumServiceProcs=" + mNumServiceProcs
13233                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13234                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13235                         + " mLastMemoryLevel" + mLastMemoryLevel
13236                         + " mLastNumProcesses" + mLastNumProcesses);
13237                 long now = SystemClock.uptimeMillis();
13238                 pw.print("  mLastIdleTime=");
13239                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13240                         pw.print(" mLowRamSinceLastIdle=");
13241                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13242                         pw.println();
13243             }
13244         }
13245
13246         if (!printedAnything) {
13247             pw.println("  (nothing)");
13248         }
13249     }
13250
13251     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13252             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13253         if (mProcessesToGc.size() > 0) {
13254             boolean printed = false;
13255             long now = SystemClock.uptimeMillis();
13256             for (int i=0; i<mProcessesToGc.size(); i++) {
13257                 ProcessRecord proc = mProcessesToGc.get(i);
13258                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13259                     continue;
13260                 }
13261                 if (!printed) {
13262                     if (needSep) pw.println();
13263                     needSep = true;
13264                     pw.println("  Processes that are waiting to GC:");
13265                     printed = true;
13266                 }
13267                 pw.print("    Process "); pw.println(proc);
13268                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13269                         pw.print(", last gced=");
13270                         pw.print(now-proc.lastRequestedGc);
13271                         pw.print(" ms ago, last lowMem=");
13272                         pw.print(now-proc.lastLowMemory);
13273                         pw.println(" ms ago");
13274
13275             }
13276         }
13277         return needSep;
13278     }
13279
13280     void printOomLevel(PrintWriter pw, String name, int adj) {
13281         pw.print("    ");
13282         if (adj >= 0) {
13283             pw.print(' ');
13284             if (adj < 10) pw.print(' ');
13285         } else {
13286             if (adj > -10) pw.print(' ');
13287         }
13288         pw.print(adj);
13289         pw.print(": ");
13290         pw.print(name);
13291         pw.print(" (");
13292         pw.print(mProcessList.getMemLevel(adj)/1024);
13293         pw.println(" kB)");
13294     }
13295
13296     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13297             int opti, boolean dumpAll) {
13298         boolean needSep = false;
13299
13300         if (mLruProcesses.size() > 0) {
13301             if (needSep) pw.println();
13302             needSep = true;
13303             pw.println("  OOM levels:");
13304             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13305             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13306             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13307             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13308             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13309             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13310             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13311             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13312             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13313             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13314             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13315             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13316             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13317             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13318
13319             if (needSep) pw.println();
13320             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13321                     pw.print(" total, non-act at ");
13322                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13323                     pw.print(", non-svc at ");
13324                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13325                     pw.println("):");
13326             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13327             needSep = true;
13328         }
13329
13330         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13331
13332         pw.println();
13333         pw.println("  mHomeProcess: " + mHomeProcess);
13334         pw.println("  mPreviousProcess: " + mPreviousProcess);
13335         if (mHeavyWeightProcess != null) {
13336             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13337         }
13338
13339         return true;
13340     }
13341
13342     /**
13343      * There are three ways to call this:
13344      *  - no provider specified: dump all the providers
13345      *  - a flattened component name that matched an existing provider was specified as the
13346      *    first arg: dump that one provider
13347      *  - the first arg isn't the flattened component name of an existing provider:
13348      *    dump all providers whose component contains the first arg as a substring
13349      */
13350     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13351             int opti, boolean dumpAll) {
13352         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13353     }
13354
13355     static class ItemMatcher {
13356         ArrayList<ComponentName> components;
13357         ArrayList<String> strings;
13358         ArrayList<Integer> objects;
13359         boolean all;
13360         
13361         ItemMatcher() {
13362             all = true;
13363         }
13364
13365         void build(String name) {
13366             ComponentName componentName = ComponentName.unflattenFromString(name);
13367             if (componentName != null) {
13368                 if (components == null) {
13369                     components = new ArrayList<ComponentName>();
13370                 }
13371                 components.add(componentName);
13372                 all = false;
13373             } else {
13374                 int objectId = 0;
13375                 // Not a '/' separated full component name; maybe an object ID?
13376                 try {
13377                     objectId = Integer.parseInt(name, 16);
13378                     if (objects == null) {
13379                         objects = new ArrayList<Integer>();
13380                     }
13381                     objects.add(objectId);
13382                     all = false;
13383                 } catch (RuntimeException e) {
13384                     // Not an integer; just do string match.
13385                     if (strings == null) {
13386                         strings = new ArrayList<String>();
13387                     }
13388                     strings.add(name);
13389                     all = false;
13390                 }
13391             }
13392         }
13393
13394         int build(String[] args, int opti) {
13395             for (; opti<args.length; opti++) {
13396                 String name = args[opti];
13397                 if ("--".equals(name)) {
13398                     return opti+1;
13399                 }
13400                 build(name);
13401             }
13402             return opti;
13403         }
13404
13405         boolean match(Object object, ComponentName comp) {
13406             if (all) {
13407                 return true;
13408             }
13409             if (components != null) {
13410                 for (int i=0; i<components.size(); i++) {
13411                     if (components.get(i).equals(comp)) {
13412                         return true;
13413                     }
13414                 }
13415             }
13416             if (objects != null) {
13417                 for (int i=0; i<objects.size(); i++) {
13418                     if (System.identityHashCode(object) == objects.get(i)) {
13419                         return true;
13420                     }
13421                 }
13422             }
13423             if (strings != null) {
13424                 String flat = comp.flattenToString();
13425                 for (int i=0; i<strings.size(); i++) {
13426                     if (flat.contains(strings.get(i))) {
13427                         return true;
13428                     }
13429                 }
13430             }
13431             return false;
13432         }
13433     }
13434
13435     /**
13436      * There are three things that cmd can be:
13437      *  - a flattened component name that matches an existing activity
13438      *  - the cmd arg isn't the flattened component name of an existing activity:
13439      *    dump all activity whose component contains the cmd as a substring
13440      *  - A hex number of the ActivityRecord object instance.
13441      */
13442     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13443             int opti, boolean dumpAll) {
13444         ArrayList<ActivityRecord> activities;
13445         
13446         synchronized (this) {
13447             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13448         }
13449
13450         if (activities.size() <= 0) {
13451             return false;
13452         }
13453
13454         String[] newArgs = new String[args.length - opti];
13455         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13456
13457         TaskRecord lastTask = null;
13458         boolean needSep = false;
13459         for (int i=activities.size()-1; i>=0; i--) {
13460             ActivityRecord r = activities.get(i);
13461             if (needSep) {
13462                 pw.println();
13463             }
13464             needSep = true;
13465             synchronized (this) {
13466                 if (lastTask != r.task) {
13467                     lastTask = r.task;
13468                     pw.print("TASK "); pw.print(lastTask.affinity);
13469                             pw.print(" id="); pw.println(lastTask.taskId);
13470                     if (dumpAll) {
13471                         lastTask.dump(pw, "  ");
13472                     }
13473                 }
13474             }
13475             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13476         }
13477         return true;
13478     }
13479
13480     /**
13481      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13482      * there is a thread associated with the activity.
13483      */
13484     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13485             final ActivityRecord r, String[] args, boolean dumpAll) {
13486         String innerPrefix = prefix + "  ";
13487         synchronized (this) {
13488             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13489                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13490                     pw.print(" pid=");
13491                     if (r.app != null) pw.println(r.app.pid);
13492                     else pw.println("(not running)");
13493             if (dumpAll) {
13494                 r.dump(pw, innerPrefix);
13495             }
13496         }
13497         if (r.app != null && r.app.thread != null) {
13498             // flush anything that is already in the PrintWriter since the thread is going
13499             // to write to the file descriptor directly
13500             pw.flush();
13501             try {
13502                 TransferPipe tp = new TransferPipe();
13503                 try {
13504                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13505                             r.appToken, innerPrefix, args);
13506                     tp.go(fd);
13507                 } finally {
13508                     tp.kill();
13509                 }
13510             } catch (IOException e) {
13511                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13512             } catch (RemoteException e) {
13513                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13514             }
13515         }
13516     }
13517
13518     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13519             int opti, boolean dumpAll, String dumpPackage) {
13520         boolean needSep = false;
13521         boolean onlyHistory = false;
13522         boolean printedAnything = false;
13523
13524         if ("history".equals(dumpPackage)) {
13525             if (opti < args.length && "-s".equals(args[opti])) {
13526                 dumpAll = false;
13527             }
13528             onlyHistory = true;
13529             dumpPackage = null;
13530         }
13531
13532         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13533         if (!onlyHistory && dumpAll) {
13534             if (mRegisteredReceivers.size() > 0) {
13535                 boolean printed = false;
13536                 Iterator it = mRegisteredReceivers.values().iterator();
13537                 while (it.hasNext()) {
13538                     ReceiverList r = (ReceiverList)it.next();
13539                     if (dumpPackage != null && (r.app == null ||
13540                             !dumpPackage.equals(r.app.info.packageName))) {
13541                         continue;
13542                     }
13543                     if (!printed) {
13544                         pw.println("  Registered Receivers:");
13545                         needSep = true;
13546                         printed = true;
13547                         printedAnything = true;
13548                     }
13549                     pw.print("  * "); pw.println(r);
13550                     r.dump(pw, "    ");
13551                 }
13552             }
13553
13554             if (mReceiverResolver.dump(pw, needSep ?
13555                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13556                     "    ", dumpPackage, false, false)) {
13557                 needSep = true;
13558                 printedAnything = true;
13559             }
13560         }
13561
13562         for (BroadcastQueue q : mBroadcastQueues) {
13563             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13564             printedAnything |= needSep;
13565         }
13566
13567         needSep = true;
13568         
13569         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13570             for (int user=0; user<mStickyBroadcasts.size(); user++) {
13571                 if (needSep) {
13572                     pw.println();
13573                 }
13574                 needSep = true;
13575                 printedAnything = true;
13576                 pw.print("  Sticky broadcasts for user ");
13577                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13578                 StringBuilder sb = new StringBuilder(128);
13579                 for (Map.Entry<String, ArrayList<Intent>> ent
13580                         : mStickyBroadcasts.valueAt(user).entrySet()) {
13581                     pw.print("  * Sticky action "); pw.print(ent.getKey());
13582                     if (dumpAll) {
13583                         pw.println(":");
13584                         ArrayList<Intent> intents = ent.getValue();
13585                         final int N = intents.size();
13586                         for (int i=0; i<N; i++) {
13587                             sb.setLength(0);
13588                             sb.append("    Intent: ");
13589                             intents.get(i).toShortString(sb, false, true, false, false);
13590                             pw.println(sb.toString());
13591                             Bundle bundle = intents.get(i).getExtras();
13592                             if (bundle != null) {
13593                                 pw.print("      ");
13594                                 pw.println(bundle.toString());
13595                             }
13596                         }
13597                     } else {
13598                         pw.println("");
13599                     }
13600                 }
13601             }
13602         }
13603         
13604         if (!onlyHistory && dumpAll) {
13605             pw.println();
13606             for (BroadcastQueue queue : mBroadcastQueues) {
13607                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13608                         + queue.mBroadcastsScheduled);
13609             }
13610             pw.println("  mHandler:");
13611             mHandler.dump(new PrintWriterPrinter(pw), "    ");
13612             needSep = true;
13613             printedAnything = true;
13614         }
13615         
13616         if (!printedAnything) {
13617             pw.println("  (nothing)");
13618         }
13619     }
13620
13621     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13622             int opti, boolean dumpAll, String dumpPackage) {
13623         boolean needSep;
13624         boolean printedAnything = false;
13625
13626         ItemMatcher matcher = new ItemMatcher();
13627         matcher.build(args, opti);
13628
13629         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13630
13631         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13632         printedAnything |= needSep;
13633
13634         if (mLaunchingProviders.size() > 0) {
13635             boolean printed = false;
13636             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13637                 ContentProviderRecord r = mLaunchingProviders.get(i);
13638                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13639                     continue;
13640                 }
13641                 if (!printed) {
13642                     if (needSep) pw.println();
13643                     needSep = true;
13644                     pw.println("  Launching content providers:");
13645                     printed = true;
13646                     printedAnything = true;
13647                 }
13648                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
13649                         pw.println(r);
13650             }
13651         }
13652
13653         if (mGrantedUriPermissions.size() > 0) {
13654             boolean printed = false;
13655             int dumpUid = -2;
13656             if (dumpPackage != null) {
13657                 try {
13658                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13659                 } catch (NameNotFoundException e) {
13660                     dumpUid = -1;
13661                 }
13662             }
13663             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13664                 int uid = mGrantedUriPermissions.keyAt(i);
13665                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13666                     continue;
13667                 }
13668                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13669                 if (!printed) {
13670                     if (needSep) pw.println();
13671                     needSep = true;
13672                     pw.println("  Granted Uri Permissions:");
13673                     printed = true;
13674                     printedAnything = true;
13675                 }
13676                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13677                 for (UriPermission perm : perms.values()) {
13678                     pw.print("    "); pw.println(perm);
13679                     if (dumpAll) {
13680                         perm.dump(pw, "      ");
13681                     }
13682                 }
13683             }
13684         }
13685
13686         if (!printedAnything) {
13687             pw.println("  (nothing)");
13688         }
13689     }
13690
13691     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13692             int opti, boolean dumpAll, String dumpPackage) {
13693         boolean printed = false;
13694
13695         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13696
13697         if (mIntentSenderRecords.size() > 0) {
13698             Iterator<WeakReference<PendingIntentRecord>> it
13699                     = mIntentSenderRecords.values().iterator();
13700             while (it.hasNext()) {
13701                 WeakReference<PendingIntentRecord> ref = it.next();
13702                 PendingIntentRecord rec = ref != null ? ref.get(): null;
13703                 if (dumpPackage != null && (rec == null
13704                         || !dumpPackage.equals(rec.key.packageName))) {
13705                     continue;
13706                 }
13707                 printed = true;
13708                 if (rec != null) {
13709                     pw.print("  * "); pw.println(rec);
13710                     if (dumpAll) {
13711                         rec.dump(pw, "    ");
13712                     }
13713                 } else {
13714                     pw.print("  * "); pw.println(ref);
13715                 }
13716             }
13717         }
13718
13719         if (!printed) {
13720             pw.println("  (nothing)");
13721         }
13722     }
13723
13724     private static final int dumpProcessList(PrintWriter pw,
13725             ActivityManagerService service, List list,
13726             String prefix, String normalLabel, String persistentLabel,
13727             String dumpPackage) {
13728         int numPers = 0;
13729         final int N = list.size()-1;
13730         for (int i=N; i>=0; i--) {
13731             ProcessRecord r = (ProcessRecord)list.get(i);
13732             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13733                 continue;
13734             }
13735             pw.println(String.format("%s%s #%2d: %s",
13736                     prefix, (r.persistent ? persistentLabel : normalLabel),
13737                     i, r.toString()));
13738             if (r.persistent) {
13739                 numPers++;
13740             }
13741         }
13742         return numPers;
13743     }
13744
13745     private static final boolean dumpProcessOomList(PrintWriter pw,
13746             ActivityManagerService service, List<ProcessRecord> origList,
13747             String prefix, String normalLabel, String persistentLabel,
13748             boolean inclDetails, String dumpPackage) {
13749
13750         ArrayList<Pair<ProcessRecord, Integer>> list
13751                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13752         for (int i=0; i<origList.size(); i++) {
13753             ProcessRecord r = origList.get(i);
13754             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13755                 continue;
13756             }
13757             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13758         }
13759
13760         if (list.size() <= 0) {
13761             return false;
13762         }
13763
13764         Comparator<Pair<ProcessRecord, Integer>> comparator
13765                 = new Comparator<Pair<ProcessRecord, Integer>>() {
13766             @Override
13767             public int compare(Pair<ProcessRecord, Integer> object1,
13768                     Pair<ProcessRecord, Integer> object2) {
13769                 if (object1.first.setAdj != object2.first.setAdj) {
13770                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13771                 }
13772                 if (object1.second.intValue() != object2.second.intValue()) {
13773                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13774                 }
13775                 return 0;
13776             }
13777         };
13778
13779         Collections.sort(list, comparator);
13780
13781         final long curRealtime = SystemClock.elapsedRealtime();
13782         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13783         final long curUptime = SystemClock.uptimeMillis();
13784         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13785
13786         for (int i=list.size()-1; i>=0; i--) {
13787             ProcessRecord r = list.get(i).first;
13788             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13789             char schedGroup;
13790             switch (r.setSchedGroup) {
13791                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13792                     schedGroup = 'B';
13793                     break;
13794                 case Process.THREAD_GROUP_DEFAULT:
13795                     schedGroup = 'F';
13796                     break;
13797                 default:
13798                     schedGroup = '?';
13799                     break;
13800             }
13801             char foreground;
13802             if (r.foregroundActivities) {
13803                 foreground = 'A';
13804             } else if (r.foregroundServices) {
13805                 foreground = 'S';
13806             } else {
13807                 foreground = ' ';
13808             }
13809             String procState = ProcessList.makeProcStateString(r.curProcState);
13810             pw.print(prefix);
13811             pw.print(r.persistent ? persistentLabel : normalLabel);
13812             pw.print(" #");
13813             int num = (origList.size()-1)-list.get(i).second;
13814             if (num < 10) pw.print(' ');
13815             pw.print(num);
13816             pw.print(": ");
13817             pw.print(oomAdj);
13818             pw.print(' ');
13819             pw.print(schedGroup);
13820             pw.print('/');
13821             pw.print(foreground);
13822             pw.print('/');
13823             pw.print(procState);
13824             pw.print(" trm:");
13825             if (r.trimMemoryLevel < 10) pw.print(' ');
13826             pw.print(r.trimMemoryLevel);
13827             pw.print(' ');
13828             pw.print(r.toShortString());
13829             pw.print(" (");
13830             pw.print(r.adjType);
13831             pw.println(')');
13832             if (r.adjSource != null || r.adjTarget != null) {
13833                 pw.print(prefix);
13834                 pw.print("    ");
13835                 if (r.adjTarget instanceof ComponentName) {
13836                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13837                 } else if (r.adjTarget != null) {
13838                     pw.print(r.adjTarget.toString());
13839                 } else {
13840                     pw.print("{null}");
13841                 }
13842                 pw.print("<=");
13843                 if (r.adjSource instanceof ProcessRecord) {
13844                     pw.print("Proc{");
13845                     pw.print(((ProcessRecord)r.adjSource).toShortString());
13846                     pw.println("}");
13847                 } else if (r.adjSource != null) {
13848                     pw.println(r.adjSource.toString());
13849                 } else {
13850                     pw.println("{null}");
13851                 }
13852             }
13853             if (inclDetails) {
13854                 pw.print(prefix);
13855                 pw.print("    ");
13856                 pw.print("oom: max="); pw.print(r.maxAdj);
13857                 pw.print(" curRaw="); pw.print(r.curRawAdj);
13858                 pw.print(" setRaw="); pw.print(r.setRawAdj);
13859                 pw.print(" cur="); pw.print(r.curAdj);
13860                 pw.print(" set="); pw.println(r.setAdj);
13861                 pw.print(prefix);
13862                 pw.print("    ");
13863                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13864                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13865                 pw.print(" lastPss="); pw.print(r.lastPss);
13866                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13867                 pw.print(prefix);
13868                 pw.print("    ");
13869                 pw.print("cached="); pw.print(r.cached);
13870                 pw.print(" empty="); pw.print(r.empty);
13871                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13872
13873                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13874                     if (r.lastWakeTime != 0) {
13875                         long wtime;
13876                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13877                         synchronized (stats) {
13878                             wtime = stats.getProcessWakeTime(r.info.uid,
13879                                     r.pid, curRealtime);
13880                         }
13881                         long timeUsed = wtime - r.lastWakeTime;
13882                         pw.print(prefix);
13883                         pw.print("    ");
13884                         pw.print("keep awake over ");
13885                         TimeUtils.formatDuration(realtimeSince, pw);
13886                         pw.print(" used ");
13887                         TimeUtils.formatDuration(timeUsed, pw);
13888                         pw.print(" (");
13889                         pw.print((timeUsed*100)/realtimeSince);
13890                         pw.println("%)");
13891                     }
13892                     if (r.lastCpuTime != 0) {
13893                         long timeUsed = r.curCpuTime - r.lastCpuTime;
13894                         pw.print(prefix);
13895                         pw.print("    ");
13896                         pw.print("run cpu over ");
13897                         TimeUtils.formatDuration(uptimeSince, pw);
13898                         pw.print(" used ");
13899                         TimeUtils.formatDuration(timeUsed, pw);
13900                         pw.print(" (");
13901                         pw.print((timeUsed*100)/uptimeSince);
13902                         pw.println("%)");
13903                     }
13904                 }
13905             }
13906         }
13907         return true;
13908     }
13909
13910     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13911             String[] args) {
13912         ArrayList<ProcessRecord> procs;
13913         synchronized (this) {
13914             if (args != null && args.length > start
13915                     && args[start].charAt(0) != '-') {
13916                 procs = new ArrayList<ProcessRecord>();
13917                 int pid = -1;
13918                 try {
13919                     pid = Integer.parseInt(args[start]);
13920                 } catch (NumberFormatException e) {
13921                 }
13922                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13923                     ProcessRecord proc = mLruProcesses.get(i);
13924                     if (proc.pid == pid) {
13925                         procs.add(proc);
13926                     } else if (allPkgs && proc.pkgList != null
13927                             && proc.pkgList.containsKey(args[start])) {
13928                         procs.add(proc);
13929                     } else if (proc.processName.equals(args[start])) {
13930                         procs.add(proc);
13931                     }
13932                 }
13933                 if (procs.size() <= 0) {
13934                     return null;
13935                 }
13936             } else {
13937                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13938             }
13939         }
13940         return procs;
13941     }
13942
13943     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13944             PrintWriter pw, String[] args) {
13945         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13946         if (procs == null) {
13947             pw.println("No process found for: " + args[0]);
13948             return;
13949         }
13950
13951         long uptime = SystemClock.uptimeMillis();
13952         long realtime = SystemClock.elapsedRealtime();
13953         pw.println("Applications Graphics Acceleration Info:");
13954         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13955         
13956         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13957             ProcessRecord r = procs.get(i);
13958             if (r.thread != null) {
13959                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13960                 pw.flush();
13961                 try {
13962                     TransferPipe tp = new TransferPipe();
13963                     try {
13964                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13965                         tp.go(fd);
13966                     } finally {
13967                         tp.kill();
13968                     }
13969                 } catch (IOException e) {
13970                     pw.println("Failure while dumping the app: " + r);
13971                     pw.flush();
13972                 } catch (RemoteException e) {
13973                     pw.println("Got a RemoteException while dumping the app " + r);
13974                     pw.flush();
13975                 }
13976             }
13977         }
13978     }
13979
13980     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13981         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13982         if (procs == null) {
13983             pw.println("No process found for: " + args[0]);
13984             return;
13985         }
13986
13987         pw.println("Applications Database Info:");
13988
13989         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13990             ProcessRecord r = procs.get(i);
13991             if (r.thread != null) {
13992                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13993                 pw.flush();
13994                 try {
13995                     TransferPipe tp = new TransferPipe();
13996                     try {
13997                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13998                         tp.go(fd);
13999                     } finally {
14000                         tp.kill();
14001                     }
14002                 } catch (IOException e) {
14003                     pw.println("Failure while dumping the app: " + r);
14004                     pw.flush();
14005                 } catch (RemoteException e) {
14006                     pw.println("Got a RemoteException while dumping the app " + r);
14007                     pw.flush();
14008                 }
14009             }
14010         }
14011     }
14012
14013     final static class MemItem {
14014         final boolean isProc;
14015         final String label;
14016         final String shortLabel;
14017         final long pss;
14018         final int id;
14019         final boolean hasActivities;
14020         ArrayList<MemItem> subitems;
14021
14022         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14023                 boolean _hasActivities) {
14024             isProc = true;
14025             label = _label;
14026             shortLabel = _shortLabel;
14027             pss = _pss;
14028             id = _id;
14029             hasActivities = _hasActivities;
14030         }
14031
14032         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14033             isProc = false;
14034             label = _label;
14035             shortLabel = _shortLabel;
14036             pss = _pss;
14037             id = _id;
14038             hasActivities = false;
14039         }
14040     }
14041
14042     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14043             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14044         if (sort && !isCompact) {
14045             Collections.sort(items, new Comparator<MemItem>() {
14046                 @Override
14047                 public int compare(MemItem lhs, MemItem rhs) {
14048                     if (lhs.pss < rhs.pss) {
14049                         return 1;
14050                     } else if (lhs.pss > rhs.pss) {
14051                         return -1;
14052                     }
14053                     return 0;
14054                 }
14055             });
14056         }
14057
14058         for (int i=0; i<items.size(); i++) {
14059             MemItem mi = items.get(i);
14060             if (!isCompact) {
14061                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14062             } else if (mi.isProc) {
14063                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14064                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14065                 pw.println(mi.hasActivities ? ",a" : ",e");
14066             } else {
14067                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14068                 pw.println(mi.pss);
14069             }
14070             if (mi.subitems != null) {
14071                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14072                         true, isCompact);
14073             }
14074         }
14075     }
14076
14077     // These are in KB.
14078     static final long[] DUMP_MEM_BUCKETS = new long[] {
14079         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14080         120*1024, 160*1024, 200*1024,
14081         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14082         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14083     };
14084
14085     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14086             boolean stackLike) {
14087         int start = label.lastIndexOf('.');
14088         if (start >= 0) start++;
14089         else start = 0;
14090         int end = label.length();
14091         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14092             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14093                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14094                 out.append(bucket);
14095                 out.append(stackLike ? "MB." : "MB ");
14096                 out.append(label, start, end);
14097                 return;
14098             }
14099         }
14100         out.append(memKB/1024);
14101         out.append(stackLike ? "MB." : "MB ");
14102         out.append(label, start, end);
14103     }
14104
14105     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14106             ProcessList.NATIVE_ADJ,
14107             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14108             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14109             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14110             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14111             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14112             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14113     };
14114     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14115             "Native",
14116             "System", "Persistent", "Persistent Service", "Foreground",
14117             "Visible", "Perceptible",
14118             "Heavy Weight", "Backup",
14119             "A Services", "Home",
14120             "Previous", "B Services", "Cached"
14121     };
14122     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14123             "native",
14124             "sys", "pers", "persvc", "fore",
14125             "vis", "percept",
14126             "heavy", "backup",
14127             "servicea", "home",
14128             "prev", "serviceb", "cached"
14129     };
14130
14131     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14132             long realtime, boolean isCheckinRequest, boolean isCompact) {
14133         if (isCheckinRequest || isCompact) {
14134             // short checkin version
14135             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14136         } else {
14137             pw.println("Applications Memory Usage (kB):");
14138             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14139         }
14140     }
14141
14142     private static final int KSM_SHARED = 0;
14143     private static final int KSM_SHARING = 1;
14144     private static final int KSM_UNSHARED = 2;
14145     private static final int KSM_VOLATILE = 3;
14146
14147     private final long[] getKsmInfo() {
14148         long[] longOut = new long[4];
14149         final int[] SINGLE_LONG_FORMAT = new int[] {
14150             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14151         };
14152         long[] longTmp = new long[1];
14153         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14154                 SINGLE_LONG_FORMAT, null, longTmp, null);
14155         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14156         longTmp[0] = 0;
14157         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14158                 SINGLE_LONG_FORMAT, null, longTmp, null);
14159         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14160         longTmp[0] = 0;
14161         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14162                 SINGLE_LONG_FORMAT, null, longTmp, null);
14163         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14164         longTmp[0] = 0;
14165         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14166                 SINGLE_LONG_FORMAT, null, longTmp, null);
14167         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14168         return longOut;
14169     }
14170
14171     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14172             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14173         boolean dumpDetails = false;
14174         boolean dumpFullDetails = false;
14175         boolean dumpDalvik = false;
14176         boolean oomOnly = false;
14177         boolean isCompact = false;
14178         boolean localOnly = false;
14179         boolean packages = false;
14180         
14181         int opti = 0;
14182         while (opti < args.length) {
14183             String opt = args[opti];
14184             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14185                 break;
14186             }
14187             opti++;
14188             if ("-a".equals(opt)) {
14189                 dumpDetails = true;
14190                 dumpFullDetails = true;
14191                 dumpDalvik = true;
14192             } else if ("-d".equals(opt)) {
14193                 dumpDalvik = true;
14194             } else if ("-c".equals(opt)) {
14195                 isCompact = true;
14196             } else if ("--oom".equals(opt)) {
14197                 oomOnly = true;
14198             } else if ("--local".equals(opt)) {
14199                 localOnly = true;
14200             } else if ("--package".equals(opt)) {
14201                 packages = true;
14202             } else if ("-h".equals(opt)) {
14203                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14204                 pw.println("  -a: include all available information for each process.");
14205                 pw.println("  -d: include dalvik details.");
14206                 pw.println("  -c: dump in a compact machine-parseable representation.");
14207                 pw.println("  --oom: only show processes organized by oom adj.");
14208                 pw.println("  --local: only collect details locally, don't call process.");
14209                 pw.println("  --package: interpret process arg as package, dumping all");
14210                 pw.println("             processes that have loaded that package.");
14211                 pw.println("If [process] is specified it can be the name or ");
14212                 pw.println("pid of a specific process to dump.");
14213                 return;
14214             } else {
14215                 pw.println("Unknown argument: " + opt + "; use -h for help");
14216             }
14217         }
14218         
14219         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14220         long uptime = SystemClock.uptimeMillis();
14221         long realtime = SystemClock.elapsedRealtime();
14222         final long[] tmpLong = new long[1];
14223
14224         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14225         if (procs == null) {
14226             // No Java processes.  Maybe they want to print a native process.
14227             if (args != null && args.length > opti
14228                     && args[opti].charAt(0) != '-') {
14229                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14230                         = new ArrayList<ProcessCpuTracker.Stats>();
14231                 updateCpuStatsNow();
14232                 int findPid = -1;
14233                 try {
14234                     findPid = Integer.parseInt(args[opti]);
14235                 } catch (NumberFormatException e) {
14236                 }
14237                 synchronized (mProcessCpuTracker) {
14238                     final int N = mProcessCpuTracker.countStats();
14239                     for (int i=0; i<N; i++) {
14240                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14241                         if (st.pid == findPid || (st.baseName != null
14242                                 && st.baseName.equals(args[opti]))) {
14243                             nativeProcs.add(st);
14244                         }
14245                     }
14246                 }
14247                 if (nativeProcs.size() > 0) {
14248                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14249                             isCompact);
14250                     Debug.MemoryInfo mi = null;
14251                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14252                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14253                         final int pid = r.pid;
14254                         if (!isCheckinRequest && dumpDetails) {
14255                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14256                         }
14257                         if (mi == null) {
14258                             mi = new Debug.MemoryInfo();
14259                         }
14260                         if (dumpDetails || (!brief && !oomOnly)) {
14261                             Debug.getMemoryInfo(pid, mi);
14262                         } else {
14263                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14264                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14265                         }
14266                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14267                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14268                         if (isCheckinRequest) {
14269                             pw.println();
14270                         }
14271                     }
14272                     return;
14273                 }
14274             }
14275             pw.println("No process found for: " + args[opti]);
14276             return;
14277         }
14278
14279         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14280             dumpDetails = true;
14281         }
14282
14283         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14284
14285         String[] innerArgs = new String[args.length-opti];
14286         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14287
14288         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14289         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14290         long nativePss = 0;
14291         long dalvikPss = 0;
14292         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14293                 EmptyArray.LONG;
14294         long otherPss = 0;
14295         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14296
14297         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14298         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14299                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14300
14301         long totalPss = 0;
14302         long cachedPss = 0;
14303
14304         Debug.MemoryInfo mi = null;
14305         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14306             final ProcessRecord r = procs.get(i);
14307             final IApplicationThread thread;
14308             final int pid;
14309             final int oomAdj;
14310             final boolean hasActivities;
14311             synchronized (this) {
14312                 thread = r.thread;
14313                 pid = r.pid;
14314                 oomAdj = r.getSetAdjWithServices();
14315                 hasActivities = r.activities.size() > 0;
14316             }
14317             if (thread != null) {
14318                 if (!isCheckinRequest && dumpDetails) {
14319                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14320                 }
14321                 if (mi == null) {
14322                     mi = new Debug.MemoryInfo();
14323                 }
14324                 if (dumpDetails || (!brief && !oomOnly)) {
14325                     Debug.getMemoryInfo(pid, mi);
14326                 } else {
14327                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14328                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14329                 }
14330                 if (dumpDetails) {
14331                     if (localOnly) {
14332                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14333                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14334                         if (isCheckinRequest) {
14335                             pw.println();
14336                         }
14337                     } else {
14338                         try {
14339                             pw.flush();
14340                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14341                                     dumpDalvik, innerArgs);
14342                         } catch (RemoteException e) {
14343                             if (!isCheckinRequest) {
14344                                 pw.println("Got RemoteException!");
14345                                 pw.flush();
14346                             }
14347                         }
14348                     }
14349                 }
14350
14351                 final long myTotalPss = mi.getTotalPss();
14352                 final long myTotalUss = mi.getTotalUss();
14353
14354                 synchronized (this) {
14355                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14356                         // Record this for posterity if the process has been stable.
14357                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14358                     }
14359                 }
14360
14361                 if (!isCheckinRequest && mi != null) {
14362                     totalPss += myTotalPss;
14363                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14364                             (hasActivities ? " / activities)" : ")"),
14365                             r.processName, myTotalPss, pid, hasActivities);
14366                     procMems.add(pssItem);
14367                     procMemsMap.put(pid, pssItem);
14368
14369                     nativePss += mi.nativePss;
14370                     dalvikPss += mi.dalvikPss;
14371                     for (int j=0; j<dalvikSubitemPss.length; j++) {
14372                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14373                     }
14374                     otherPss += mi.otherPss;
14375                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14376                         long mem = mi.getOtherPss(j);
14377                         miscPss[j] += mem;
14378                         otherPss -= mem;
14379                     }
14380
14381                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14382                         cachedPss += myTotalPss;
14383                     }
14384
14385                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14386                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14387                                 || oomIndex == (oomPss.length-1)) {
14388                             oomPss[oomIndex] += myTotalPss;
14389                             if (oomProcs[oomIndex] == null) {
14390                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14391                             }
14392                             oomProcs[oomIndex].add(pssItem);
14393                             break;
14394                         }
14395                     }
14396                 }
14397             }
14398         }
14399
14400         long nativeProcTotalPss = 0;
14401
14402         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14403             // If we are showing aggregations, also look for native processes to
14404             // include so that our aggregations are more accurate.
14405             updateCpuStatsNow();
14406             mi = null;
14407             synchronized (mProcessCpuTracker) {
14408                 final int N = mProcessCpuTracker.countStats();
14409                 for (int i=0; i<N; i++) {
14410                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14411                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14412                         if (mi == null) {
14413                             mi = new Debug.MemoryInfo();
14414                         }
14415                         if (!brief && !oomOnly) {
14416                             Debug.getMemoryInfo(st.pid, mi);
14417                         } else {
14418                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14419                             mi.nativePrivateDirty = (int)tmpLong[0];
14420                         }
14421
14422                         final long myTotalPss = mi.getTotalPss();
14423                         totalPss += myTotalPss;
14424                         nativeProcTotalPss += myTotalPss;
14425
14426                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14427                                 st.name, myTotalPss, st.pid, false);
14428                         procMems.add(pssItem);
14429
14430                         nativePss += mi.nativePss;
14431                         dalvikPss += mi.dalvikPss;
14432                         for (int j=0; j<dalvikSubitemPss.length; j++) {
14433                             dalvikSubitemPss[j] += mi.getOtherPss(
14434                                     Debug.MemoryInfo.NUM_OTHER_STATS + j);
14435                         }
14436                         otherPss += mi.otherPss;
14437                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14438                             long mem = mi.getOtherPss(j);
14439                             miscPss[j] += mem;
14440                             otherPss -= mem;
14441                         }
14442                         oomPss[0] += myTotalPss;
14443                         if (oomProcs[0] == null) {
14444                             oomProcs[0] = new ArrayList<MemItem>();
14445                         }
14446                         oomProcs[0].add(pssItem);
14447                     }
14448                 }
14449             }
14450
14451             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14452
14453             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14454             final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14455             if (dalvikSubitemPss.length > 0) {
14456                 dalvikItem.subitems = new ArrayList<MemItem>();
14457                 for (int j=0; j<dalvikSubitemPss.length; j++) {
14458                     final String name = Debug.MemoryInfo.getOtherLabel(
14459                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
14460                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14461                 }
14462             }
14463             catMems.add(dalvikItem);
14464             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14465             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14466                 String label = Debug.MemoryInfo.getOtherLabel(j);
14467                 catMems.add(new MemItem(label, label, miscPss[j], j));
14468             }
14469
14470             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14471             for (int j=0; j<oomPss.length; j++) {
14472                 if (oomPss[j] != 0) {
14473                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14474                             : DUMP_MEM_OOM_LABEL[j];
14475                     MemItem item = new MemItem(label, label, oomPss[j],
14476                             DUMP_MEM_OOM_ADJ[j]);
14477                     item.subitems = oomProcs[j];
14478                     oomMems.add(item);
14479                 }
14480             }
14481
14482             if (!brief && !oomOnly && !isCompact) {
14483                 pw.println();
14484                 pw.println("Total PSS by process:");
14485                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14486                 pw.println();
14487             }
14488             if (!isCompact) {
14489                 pw.println("Total PSS by OOM adjustment:");
14490             }
14491             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14492             if (!brief && !oomOnly) {
14493                 PrintWriter out = categoryPw != null ? categoryPw : pw;
14494                 if (!isCompact) {
14495                     out.println();
14496                     out.println("Total PSS by category:");
14497                 }
14498                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14499             }
14500             if (!isCompact) {
14501                 pw.println();
14502             }
14503             MemInfoReader memInfo = new MemInfoReader();
14504             memInfo.readMemInfo();
14505             if (nativeProcTotalPss > 0) {
14506                 synchronized (this) {
14507                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14508                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14509                             memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14510                 }
14511             }
14512             if (!brief) {
14513                 if (!isCompact) {
14514                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14515                     pw.print(" kB (status ");
14516                     switch (mLastMemoryLevel) {
14517                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14518                             pw.println("normal)");
14519                             break;
14520                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14521                             pw.println("moderate)");
14522                             break;
14523                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
14524                             pw.println("low)");
14525                             break;
14526                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14527                             pw.println("critical)");
14528                             break;
14529                         default:
14530                             pw.print(mLastMemoryLevel);
14531                             pw.println(")");
14532                             break;
14533                     }
14534                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14535                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
14536                             pw.print(cachedPss); pw.print(" cached pss + ");
14537                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14538                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14539                 } else {
14540                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14541                     pw.print(cachedPss + memInfo.getCachedSizeKb()
14542                             + memInfo.getFreeSizeKb()); pw.print(",");
14543                     pw.println(totalPss - cachedPss);
14544                 }
14545             }
14546             if (!isCompact) {
14547                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14548                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14549                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14550                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14551                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14552                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14553                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14554             }
14555             if (!brief) {
14556                 if (memInfo.getZramTotalSizeKb() != 0) {
14557                     if (!isCompact) {
14558                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14559                                 pw.print(" kB physical used for ");
14560                                 pw.print(memInfo.getSwapTotalSizeKb()
14561                                         - memInfo.getSwapFreeSizeKb());
14562                                 pw.print(" kB in swap (");
14563                                 pw.print(memInfo.getSwapTotalSizeKb());
14564                                 pw.println(" kB total swap)");
14565                     } else {
14566                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14567                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14568                                 pw.println(memInfo.getSwapFreeSizeKb());
14569                     }
14570                 }
14571                 final long[] ksm = getKsmInfo();
14572                 if (!isCompact) {
14573                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14574                             || ksm[KSM_VOLATILE] != 0) {
14575                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14576                                 pw.print(" kB saved from shared ");
14577                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14578                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14579                                 pw.print(" kB unshared; ");
14580                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14581                     }
14582                     pw.print("   Tuning: ");
14583                     pw.print(ActivityManager.staticGetMemoryClass());
14584                     pw.print(" (large ");
14585                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14586                     pw.print("), oom ");
14587                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14588                     pw.print(" kB");
14589                     pw.print(", restore limit ");
14590                     pw.print(mProcessList.getCachedRestoreThresholdKb());
14591                     pw.print(" kB");
14592                     if (ActivityManager.isLowRamDeviceStatic()) {
14593                         pw.print(" (low-ram)");
14594                     }
14595                     if (ActivityManager.isHighEndGfx()) {
14596                         pw.print(" (high-end-gfx)");
14597                     }
14598                     pw.println();
14599                 } else {
14600                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14601                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14602                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14603                     pw.print("tuning,");
14604                     pw.print(ActivityManager.staticGetMemoryClass());
14605                     pw.print(',');
14606                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14607                     pw.print(',');
14608                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14609                     if (ActivityManager.isLowRamDeviceStatic()) {
14610                         pw.print(",low-ram");
14611                     }
14612                     if (ActivityManager.isHighEndGfx()) {
14613                         pw.print(",high-end-gfx");
14614                     }
14615                     pw.println();
14616                 }
14617             }
14618         }
14619     }
14620
14621     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14622             long memtrack, String name) {
14623         sb.append("  ");
14624         sb.append(ProcessList.makeOomAdjString(oomAdj));
14625         sb.append(' ');
14626         sb.append(ProcessList.makeProcStateString(procState));
14627         sb.append(' ');
14628         ProcessList.appendRamKb(sb, pss);
14629         sb.append(" kB: ");
14630         sb.append(name);
14631         if (memtrack > 0) {
14632             sb.append(" (");
14633             sb.append(memtrack);
14634             sb.append(" kB memtrack)");
14635         }
14636     }
14637
14638     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14639         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14640         sb.append(" (pid ");
14641         sb.append(mi.pid);
14642         sb.append(") ");
14643         sb.append(mi.adjType);
14644         sb.append('\n');
14645         if (mi.adjReason != null) {
14646             sb.append("                      ");
14647             sb.append(mi.adjReason);
14648             sb.append('\n');
14649         }
14650     }
14651
14652     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14653         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14654         for (int i=0, N=memInfos.size(); i<N; i++) {
14655             ProcessMemInfo mi = memInfos.get(i);
14656             infoMap.put(mi.pid, mi);
14657         }
14658         updateCpuStatsNow();
14659         long[] memtrackTmp = new long[1];
14660         synchronized (mProcessCpuTracker) {
14661             final int N = mProcessCpuTracker.countStats();
14662             for (int i=0; i<N; i++) {
14663                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14664                 if (st.vsize > 0) {
14665                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
14666                     if (pss > 0) {
14667                         if (infoMap.indexOfKey(st.pid) < 0) {
14668                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14669                                     ProcessList.NATIVE_ADJ, -1, "native", null);
14670                             mi.pss = pss;
14671                             mi.memtrack = memtrackTmp[0];
14672                             memInfos.add(mi);
14673                         }
14674                     }
14675                 }
14676             }
14677         }
14678
14679         long totalPss = 0;
14680         long totalMemtrack = 0;
14681         for (int i=0, N=memInfos.size(); i<N; i++) {
14682             ProcessMemInfo mi = memInfos.get(i);
14683             if (mi.pss == 0) {
14684                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14685                 mi.memtrack = memtrackTmp[0];
14686             }
14687             totalPss += mi.pss;
14688             totalMemtrack += mi.memtrack;
14689         }
14690         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14691             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14692                 if (lhs.oomAdj != rhs.oomAdj) {
14693                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14694                 }
14695                 if (lhs.pss != rhs.pss) {
14696                     return lhs.pss < rhs.pss ? 1 : -1;
14697                 }
14698                 return 0;
14699             }
14700         });
14701
14702         StringBuilder tag = new StringBuilder(128);
14703         StringBuilder stack = new StringBuilder(128);
14704         tag.append("Low on memory -- ");
14705         appendMemBucket(tag, totalPss, "total", false);
14706         appendMemBucket(stack, totalPss, "total", true);
14707
14708         StringBuilder fullNativeBuilder = new StringBuilder(1024);
14709         StringBuilder shortNativeBuilder = new StringBuilder(1024);
14710         StringBuilder fullJavaBuilder = new StringBuilder(1024);
14711
14712         boolean firstLine = true;
14713         int lastOomAdj = Integer.MIN_VALUE;
14714         long extraNativeRam = 0;
14715         long extraNativeMemtrack = 0;
14716         long cachedPss = 0;
14717         for (int i=0, N=memInfos.size(); i<N; i++) {
14718             ProcessMemInfo mi = memInfos.get(i);
14719
14720             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14721                 cachedPss += mi.pss;
14722             }
14723
14724             if (mi.oomAdj != ProcessList.NATIVE_ADJ
14725                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
14726                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
14727                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14728                 if (lastOomAdj != mi.oomAdj) {
14729                     lastOomAdj = mi.oomAdj;
14730                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14731                         tag.append(" / ");
14732                     }
14733                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14734                         if (firstLine) {
14735                             stack.append(":");
14736                             firstLine = false;
14737                         }
14738                         stack.append("\n\t at ");
14739                     } else {
14740                         stack.append("$");
14741                     }
14742                 } else {
14743                     tag.append(" ");
14744                     stack.append("$");
14745                 }
14746                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14747                     appendMemBucket(tag, mi.pss, mi.name, false);
14748                 }
14749                 appendMemBucket(stack, mi.pss, mi.name, true);
14750                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14751                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14752                     stack.append("(");
14753                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14754                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14755                             stack.append(DUMP_MEM_OOM_LABEL[k]);
14756                             stack.append(":");
14757                             stack.append(DUMP_MEM_OOM_ADJ[k]);
14758                         }
14759                     }
14760                     stack.append(")");
14761                 }
14762             }
14763
14764             appendMemInfo(fullNativeBuilder, mi);
14765             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14766                 // The short form only has native processes that are >= 512K.
14767                 if (mi.pss >= 512) {
14768                     appendMemInfo(shortNativeBuilder, mi);
14769                 } else {
14770                     extraNativeRam += mi.pss;
14771                     extraNativeMemtrack += mi.memtrack;
14772                 }
14773             } else {
14774                 // Short form has all other details, but if we have collected RAM
14775                 // from smaller native processes let's dump a summary of that.
14776                 if (extraNativeRam > 0) {
14777                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14778                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14779                     shortNativeBuilder.append('\n');
14780                     extraNativeRam = 0;
14781                 }
14782                 appendMemInfo(fullJavaBuilder, mi);
14783             }
14784         }
14785
14786         fullJavaBuilder.append("           ");
14787         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14788         fullJavaBuilder.append(" kB: TOTAL");
14789         if (totalMemtrack > 0) {
14790             fullJavaBuilder.append(" (");
14791             fullJavaBuilder.append(totalMemtrack);
14792             fullJavaBuilder.append(" kB memtrack)");
14793         } else {
14794         }
14795         fullJavaBuilder.append("\n");
14796
14797         MemInfoReader memInfo = new MemInfoReader();
14798         memInfo.readMemInfo();
14799         final long[] infos = memInfo.getRawInfo();
14800
14801         StringBuilder memInfoBuilder = new StringBuilder(1024);
14802         Debug.getMemInfo(infos);
14803         memInfoBuilder.append("  MemInfo: ");
14804         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14805         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14806         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14807         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14808         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14809         memInfoBuilder.append("           ");
14810         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14811         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14812         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14813         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14814         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14815             memInfoBuilder.append("  ZRAM: ");
14816             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14817             memInfoBuilder.append(" kB RAM, ");
14818             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14819             memInfoBuilder.append(" kB swap total, ");
14820             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14821             memInfoBuilder.append(" kB swap free\n");
14822         }
14823         final long[] ksm = getKsmInfo();
14824         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14825                 || ksm[KSM_VOLATILE] != 0) {
14826             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14827             memInfoBuilder.append(" kB saved from shared ");
14828             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14829             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14830             memInfoBuilder.append(" kB unshared; ");
14831             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14832         }
14833         memInfoBuilder.append("  Free RAM: ");
14834         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14835                 + memInfo.getFreeSizeKb());
14836         memInfoBuilder.append(" kB\n");
14837         memInfoBuilder.append("  Used RAM: ");
14838         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14839         memInfoBuilder.append(" kB\n");
14840         memInfoBuilder.append("  Lost RAM: ");
14841         memInfoBuilder.append(memInfo.getTotalSizeKb()
14842                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14843                 - memInfo.getKernelUsedSizeKb());
14844         memInfoBuilder.append(" kB\n");
14845         Slog.i(TAG, "Low on memory:");
14846         Slog.i(TAG, shortNativeBuilder.toString());
14847         Slog.i(TAG, fullJavaBuilder.toString());
14848         Slog.i(TAG, memInfoBuilder.toString());
14849
14850         StringBuilder dropBuilder = new StringBuilder(1024);
14851         /*
14852         StringWriter oomSw = new StringWriter();
14853         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14854         StringWriter catSw = new StringWriter();
14855         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14856         String[] emptyArgs = new String[] { };
14857         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14858         oomPw.flush();
14859         String oomString = oomSw.toString();
14860         */
14861         dropBuilder.append("Low on memory:");
14862         dropBuilder.append(stack);
14863         dropBuilder.append('\n');
14864         dropBuilder.append(fullNativeBuilder);
14865         dropBuilder.append(fullJavaBuilder);
14866         dropBuilder.append('\n');
14867         dropBuilder.append(memInfoBuilder);
14868         dropBuilder.append('\n');
14869         /*
14870         dropBuilder.append(oomString);
14871         dropBuilder.append('\n');
14872         */
14873         StringWriter catSw = new StringWriter();
14874         synchronized (ActivityManagerService.this) {
14875             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14876             String[] emptyArgs = new String[] { };
14877             catPw.println();
14878             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14879             catPw.println();
14880             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14881                     false, false, null);
14882             catPw.println();
14883             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14884             catPw.flush();
14885         }
14886         dropBuilder.append(catSw.toString());
14887         addErrorToDropBox("lowmem", null, "system_server", null,
14888                 null, tag.toString(), dropBuilder.toString(), null, null);
14889         //Slog.i(TAG, "Sent to dropbox:");
14890         //Slog.i(TAG, dropBuilder.toString());
14891         synchronized (ActivityManagerService.this) {
14892             long now = SystemClock.uptimeMillis();
14893             if (mLastMemUsageReportTime < now) {
14894                 mLastMemUsageReportTime = now;
14895             }
14896         }
14897     }
14898
14899     /**
14900      * Searches array of arguments for the specified string
14901      * @param args array of argument strings
14902      * @param value value to search for
14903      * @return true if the value is contained in the array
14904      */
14905     private static boolean scanArgs(String[] args, String value) {
14906         if (args != null) {
14907             for (String arg : args) {
14908                 if (value.equals(arg)) {
14909                     return true;
14910                 }
14911             }
14912         }
14913         return false;
14914     }
14915
14916     private final boolean removeDyingProviderLocked(ProcessRecord proc,
14917             ContentProviderRecord cpr, boolean always) {
14918         final boolean inLaunching = mLaunchingProviders.contains(cpr);
14919
14920         if (!inLaunching || always) {
14921             synchronized (cpr) {
14922                 cpr.launchingApp = null;
14923                 cpr.notifyAll();
14924             }
14925             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14926             String names[] = cpr.info.authority.split(";");
14927             for (int j = 0; j < names.length; j++) {
14928                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14929             }
14930         }
14931
14932         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
14933             ContentProviderConnection conn = cpr.connections.get(i);
14934             if (conn.waiting) {
14935                 // If this connection is waiting for the provider, then we don't
14936                 // need to mess with its process unless we are always removing
14937                 // or for some reason the provider is not currently launching.
14938                 if (inLaunching && !always) {
14939                     continue;
14940                 }
14941             }
14942             ProcessRecord capp = conn.client;
14943             conn.dead = true;
14944             if (conn.stableCount > 0) {
14945                 if (!capp.persistent && capp.thread != null
14946                         && capp.pid != 0
14947                         && capp.pid != MY_PID) {
14948                     capp.kill("depends on provider "
14949                             + cpr.name.flattenToShortString()
14950                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14951                 }
14952             } else if (capp.thread != null && conn.provider.provider != null) {
14953                 try {
14954                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14955                 } catch (RemoteException e) {
14956                 }
14957                 // In the protocol here, we don't expect the client to correctly
14958                 // clean up this connection, we'll just remove it.
14959                 cpr.connections.remove(i);
14960                 if (conn.client.conProviders.remove(conn)) {
14961                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14962                 }
14963             }
14964         }
14965
14966         if (inLaunching && always) {
14967             mLaunchingProviders.remove(cpr);
14968         }
14969         return inLaunching;
14970     }
14971
14972     /**
14973      * Main code for cleaning up a process when it has gone away.  This is
14974      * called both as a result of the process dying, or directly when stopping
14975      * a process when running in single process mode.
14976      *
14977      * @return Returns true if the given process has been restarted, so the
14978      * app that was passed in must remain on the process lists.
14979      */
14980     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14981             boolean restarting, boolean allowRestart, int index) {
14982         if (index >= 0) {
14983             removeLruProcessLocked(app);
14984             ProcessList.remove(app.pid);
14985         }
14986
14987         mProcessesToGc.remove(app);
14988         mPendingPssProcesses.remove(app);
14989
14990         // Dismiss any open dialogs.
14991         if (app.crashDialog != null && !app.forceCrashReport) {
14992             app.crashDialog.dismiss();
14993             app.crashDialog = null;
14994         }
14995         if (app.anrDialog != null) {
14996             app.anrDialog.dismiss();
14997             app.anrDialog = null;
14998         }
14999         if (app.waitDialog != null) {
15000             app.waitDialog.dismiss();
15001             app.waitDialog = null;
15002         }
15003
15004         app.crashing = false;
15005         app.notResponding = false;
15006
15007         app.resetPackageList(mProcessStats);
15008         app.unlinkDeathRecipient();
15009         app.makeInactive(mProcessStats);
15010         app.waitingToKill = null;
15011         app.forcingToForeground = null;
15012         updateProcessForegroundLocked(app, false, false);
15013         app.foregroundActivities = false;
15014         app.hasShownUi = false;
15015         app.treatLikeActivity = false;
15016         app.hasAboveClient = false;
15017         app.hasClientActivities = false;
15018
15019         mServices.killServicesLocked(app, allowRestart);
15020
15021         boolean restart = false;
15022
15023         // Remove published content providers.
15024         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15025             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15026             final boolean always = app.bad || !allowRestart;
15027             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15028             if ((inLaunching || always) && !cpr.connections.isEmpty()) {
15029                 // We left the provider in the launching list, need to
15030                 // restart it.
15031                 restart = true;
15032             }
15033
15034             cpr.provider = null;
15035             cpr.proc = null;
15036         }
15037         app.pubProviders.clear();
15038
15039         // Take care of any launching providers waiting for this process.
15040         if (checkAppInLaunchingProvidersLocked(app, false)) {
15041             restart = true;
15042         }
15043
15044         // Unregister from connected content providers.
15045         if (!app.conProviders.isEmpty()) {
15046             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15047                 ContentProviderConnection conn = app.conProviders.get(i);
15048                 conn.provider.connections.remove(conn);
15049                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15050                         conn.provider.name);
15051             }
15052             app.conProviders.clear();
15053         }
15054
15055         // At this point there may be remaining entries in mLaunchingProviders
15056         // where we were the only one waiting, so they are no longer of use.
15057         // Look for these and clean up if found.
15058         // XXX Commented out for now.  Trying to figure out a way to reproduce
15059         // the actual situation to identify what is actually going on.
15060         if (false) {
15061             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15062                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15063                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15064                     synchronized (cpr) {
15065                         cpr.launchingApp = null;
15066                         cpr.notifyAll();
15067                     }
15068                 }
15069             }
15070         }
15071
15072         skipCurrentReceiverLocked(app);
15073
15074         // Unregister any receivers.
15075         for (int i = app.receivers.size() - 1; i >= 0; i--) {
15076             removeReceiverLocked(app.receivers.valueAt(i));
15077         }
15078         app.receivers.clear();
15079
15080         // If the app is undergoing backup, tell the backup manager about it
15081         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15082             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
15083                     + mBackupTarget.appInfo + " died during backup");
15084             try {
15085                 IBackupManager bm = IBackupManager.Stub.asInterface(
15086                         ServiceManager.getService(Context.BACKUP_SERVICE));
15087                 bm.agentDisconnected(app.info.packageName);
15088             } catch (RemoteException e) {
15089                 // can't happen; backup manager is local
15090             }
15091         }
15092
15093         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15094             ProcessChangeItem item = mPendingProcessChanges.get(i);
15095             if (item.pid == app.pid) {
15096                 mPendingProcessChanges.remove(i);
15097                 mAvailProcessChanges.add(item);
15098             }
15099         }
15100         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15101
15102         // If the caller is restarting this app, then leave it in its
15103         // current lists and let the caller take care of it.
15104         if (restarting) {
15105             return false;
15106         }
15107
15108         if (!app.persistent || app.isolated) {
15109             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15110                     "Removing non-persistent process during cleanup: " + app);
15111             mProcessNames.remove(app.processName, app.uid);
15112             mIsolatedProcesses.remove(app.uid);
15113             if (mHeavyWeightProcess == app) {
15114                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15115                         mHeavyWeightProcess.userId, 0));
15116                 mHeavyWeightProcess = null;
15117             }
15118         } else if (!app.removed) {
15119             // This app is persistent, so we need to keep its record around.
15120             // If it is not already on the pending app list, add it there
15121             // and start a new process for it.
15122             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15123                 mPersistentStartingProcesses.add(app);
15124                 restart = true;
15125             }
15126         }
15127         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15128                 "Clean-up removing on hold: " + app);
15129         mProcessesOnHold.remove(app);
15130
15131         if (app == mHomeProcess) {
15132             mHomeProcess = null;
15133         }
15134         if (app == mPreviousProcess) {
15135             mPreviousProcess = null;
15136         }
15137
15138         if (restart && !app.isolated) {
15139             // We have components that still need to be running in the
15140             // process, so re-launch it.
15141             if (index < 0) {
15142                 ProcessList.remove(app.pid);
15143             }
15144             mProcessNames.put(app.processName, app.uid, app);
15145             startProcessLocked(app, "restart", app.processName);
15146             return true;
15147         } else if (app.pid > 0 && app.pid != MY_PID) {
15148             // Goodbye!
15149             boolean removed;
15150             synchronized (mPidsSelfLocked) {
15151                 mPidsSelfLocked.remove(app.pid);
15152                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15153             }
15154             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15155             if (app.isolated) {
15156                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15157             }
15158             app.setPid(0);
15159         }
15160         return false;
15161     }
15162
15163     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15164         // Look through the content providers we are waiting to have launched,
15165         // and if any run in this process then either schedule a restart of
15166         // the process or kill the client waiting for it if this process has
15167         // gone bad.
15168         boolean restart = false;
15169         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15170             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15171             if (cpr.launchingApp == app) {
15172                 if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
15173                     restart = true;
15174                 } else {
15175                     removeDyingProviderLocked(app, cpr, true);
15176                 }
15177             }
15178         }
15179         return restart;
15180     }
15181     
15182     // =========================================================
15183     // SERVICES
15184     // =========================================================
15185
15186     @Override
15187     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15188             int flags) {
15189         enforceNotIsolatedCaller("getServices");
15190         synchronized (this) {
15191             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15192         }
15193     }
15194
15195     @Override
15196     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15197         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15198         synchronized (this) {
15199             return mServices.getRunningServiceControlPanelLocked(name);
15200         }
15201     }
15202
15203     @Override
15204     public ComponentName startService(IApplicationThread caller, Intent service,
15205             String resolvedType, int userId) {
15206         enforceNotIsolatedCaller("startService");
15207         // Refuse possible leaked file descriptors
15208         if (service != null && service.hasFileDescriptors() == true) {
15209             throw new IllegalArgumentException("File descriptors passed in Intent");
15210         }
15211
15212         if (DEBUG_SERVICE)
15213             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15214         synchronized(this) {
15215             final int callingPid = Binder.getCallingPid();
15216             final int callingUid = Binder.getCallingUid();
15217             final long origId = Binder.clearCallingIdentity();
15218             ComponentName res = mServices.startServiceLocked(caller, service,
15219                     resolvedType, callingPid, callingUid, userId);
15220             Binder.restoreCallingIdentity(origId);
15221             return res;
15222         }
15223     }
15224
15225     ComponentName startServiceInPackage(int uid,
15226             Intent service, String resolvedType, int userId) {
15227         synchronized(this) {
15228             if (DEBUG_SERVICE)
15229                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15230             final long origId = Binder.clearCallingIdentity();
15231             ComponentName res = mServices.startServiceLocked(null, service,
15232                     resolvedType, -1, uid, userId);
15233             Binder.restoreCallingIdentity(origId);
15234             return res;
15235         }
15236     }
15237
15238     @Override
15239     public int stopService(IApplicationThread caller, Intent service,
15240             String resolvedType, int userId) {
15241         enforceNotIsolatedCaller("stopService");
15242         // Refuse possible leaked file descriptors
15243         if (service != null && service.hasFileDescriptors() == true) {
15244             throw new IllegalArgumentException("File descriptors passed in Intent");
15245         }
15246
15247         synchronized(this) {
15248             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15249         }
15250     }
15251
15252     @Override
15253     public IBinder peekService(Intent service, String resolvedType) {
15254         enforceNotIsolatedCaller("peekService");
15255         // Refuse possible leaked file descriptors
15256         if (service != null && service.hasFileDescriptors() == true) {
15257             throw new IllegalArgumentException("File descriptors passed in Intent");
15258         }
15259         synchronized(this) {
15260             return mServices.peekServiceLocked(service, resolvedType);
15261         }
15262     }
15263     
15264     @Override
15265     public boolean stopServiceToken(ComponentName className, IBinder token,
15266             int startId) {
15267         synchronized(this) {
15268             return mServices.stopServiceTokenLocked(className, token, startId);
15269         }
15270     }
15271
15272     @Override
15273     public void setServiceForeground(ComponentName className, IBinder token,
15274             int id, Notification notification, boolean removeNotification) {
15275         synchronized(this) {
15276             mServices.setServiceForegroundLocked(className, token, id, notification,
15277                     removeNotification);
15278         }
15279     }
15280
15281     @Override
15282     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15283             boolean requireFull, String name, String callerPackage) {
15284         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15285                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15286     }
15287
15288     int unsafeConvertIncomingUser(int userId) {
15289         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15290                 ? mCurrentUserId : userId;
15291     }
15292
15293     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15294             int allowMode, String name, String callerPackage) {
15295         final int callingUserId = UserHandle.getUserId(callingUid);
15296         if (callingUserId == userId) {
15297             return userId;
15298         }
15299
15300         // Note that we may be accessing mCurrentUserId outside of a lock...
15301         // shouldn't be a big deal, if this is being called outside
15302         // of a locked context there is intrinsically a race with
15303         // the value the caller will receive and someone else changing it.
15304         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15305         // we will switch to the calling user if access to the current user fails.
15306         int targetUserId = unsafeConvertIncomingUser(userId);
15307
15308         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15309             final boolean allow;
15310             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15311                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15312                 // If the caller has this permission, they always pass go.  And collect $200.
15313                 allow = true;
15314             } else if (allowMode == ALLOW_FULL_ONLY) {
15315                 // We require full access, sucks to be you.
15316                 allow = false;
15317             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15318                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15319                 // If the caller does not have either permission, they are always doomed.
15320                 allow = false;
15321             } else if (allowMode == ALLOW_NON_FULL) {
15322                 // We are blanket allowing non-full access, you lucky caller!
15323                 allow = true;
15324             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15325                 // We may or may not allow this depending on whether the two users are
15326                 // in the same profile.
15327                 synchronized (mUserProfileGroupIdsSelfLocked) {
15328                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15329                             UserInfo.NO_PROFILE_GROUP_ID);
15330                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15331                             UserInfo.NO_PROFILE_GROUP_ID);
15332                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15333                             && callingProfile == targetProfile;
15334                 }
15335             } else {
15336                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15337             }
15338             if (!allow) {
15339                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15340                     // In this case, they would like to just execute as their
15341                     // owner user instead of failing.
15342                     targetUserId = callingUserId;
15343                 } else {
15344                     StringBuilder builder = new StringBuilder(128);
15345                     builder.append("Permission Denial: ");
15346                     builder.append(name);
15347                     if (callerPackage != null) {
15348                         builder.append(" from ");
15349                         builder.append(callerPackage);
15350                     }
15351                     builder.append(" asks to run as user ");
15352                     builder.append(userId);
15353                     builder.append(" but is calling from user ");
15354                     builder.append(UserHandle.getUserId(callingUid));
15355                     builder.append("; this requires ");
15356                     builder.append(INTERACT_ACROSS_USERS_FULL);
15357                     if (allowMode != ALLOW_FULL_ONLY) {
15358                         builder.append(" or ");
15359                         builder.append(INTERACT_ACROSS_USERS);
15360                     }
15361                     String msg = builder.toString();
15362                     Slog.w(TAG, msg);
15363                     throw new SecurityException(msg);
15364                 }
15365             }
15366         }
15367         if (!allowAll && targetUserId < 0) {
15368             throw new IllegalArgumentException(
15369                     "Call does not support special user #" + targetUserId);
15370         }
15371         // Check shell permission
15372         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15373             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15374                     targetUserId)) {
15375                 throw new SecurityException("Shell does not have permission to access user "
15376                         + targetUserId + "\n " + Debug.getCallers(3));
15377             }
15378         }
15379         return targetUserId;
15380     }
15381
15382     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15383             String className, int flags) {
15384         boolean result = false;
15385         // For apps that don't have pre-defined UIDs, check for permission
15386         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15387             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15388                 if (ActivityManager.checkUidPermission(
15389                         INTERACT_ACROSS_USERS,
15390                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15391                     ComponentName comp = new ComponentName(aInfo.packageName, className);
15392                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
15393                             + " requests FLAG_SINGLE_USER, but app does not hold "
15394                             + INTERACT_ACROSS_USERS;
15395                     Slog.w(TAG, msg);
15396                     throw new SecurityException(msg);
15397                 }
15398                 // Permission passed
15399                 result = true;
15400             }
15401         } else if ("system".equals(componentProcessName)) {
15402             result = true;
15403         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15404             // Phone app and persistent apps are allowed to export singleuser providers.
15405             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15406                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15407         }
15408         if (DEBUG_MU) {
15409             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15410                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15411         }
15412         return result;
15413     }
15414
15415     /**
15416      * Checks to see if the caller is in the same app as the singleton
15417      * component, or the component is in a special app. It allows special apps
15418      * to export singleton components but prevents exporting singleton
15419      * components for regular apps.
15420      */
15421     boolean isValidSingletonCall(int callingUid, int componentUid) {
15422         int componentAppId = UserHandle.getAppId(componentUid);
15423         return UserHandle.isSameApp(callingUid, componentUid)
15424                 || componentAppId == Process.SYSTEM_UID
15425                 || componentAppId == Process.PHONE_UID
15426                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15427                         == PackageManager.PERMISSION_GRANTED;
15428     }
15429
15430     public int bindService(IApplicationThread caller, IBinder token,
15431             Intent service, String resolvedType,
15432             IServiceConnection connection, int flags, int userId) {
15433         enforceNotIsolatedCaller("bindService");
15434
15435         // Refuse possible leaked file descriptors
15436         if (service != null && service.hasFileDescriptors() == true) {
15437             throw new IllegalArgumentException("File descriptors passed in Intent");
15438         }
15439
15440         synchronized(this) {
15441             return mServices.bindServiceLocked(caller, token, service, resolvedType,
15442                     connection, flags, userId);
15443         }
15444     }
15445
15446     public boolean unbindService(IServiceConnection connection) {
15447         synchronized (this) {
15448             return mServices.unbindServiceLocked(connection);
15449         }
15450     }
15451
15452     public void publishService(IBinder token, Intent intent, IBinder service) {
15453         // Refuse possible leaked file descriptors
15454         if (intent != null && intent.hasFileDescriptors() == true) {
15455             throw new IllegalArgumentException("File descriptors passed in Intent");
15456         }
15457
15458         synchronized(this) {
15459             if (!(token instanceof ServiceRecord)) {
15460                 throw new IllegalArgumentException("Invalid service token");
15461             }
15462             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15463         }
15464     }
15465
15466     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15467         // Refuse possible leaked file descriptors
15468         if (intent != null && intent.hasFileDescriptors() == true) {
15469             throw new IllegalArgumentException("File descriptors passed in Intent");
15470         }
15471
15472         synchronized(this) {
15473             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15474         }
15475     }
15476
15477     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15478         synchronized(this) {
15479             if (!(token instanceof ServiceRecord)) {
15480                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15481                 throw new IllegalArgumentException("Invalid service token");
15482             }
15483             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15484         }
15485     }
15486     
15487     // =========================================================
15488     // BACKUP AND RESTORE
15489     // =========================================================
15490     
15491     // Cause the target app to be launched if necessary and its backup agent
15492     // instantiated.  The backup agent will invoke backupAgentCreated() on the
15493     // activity manager to announce its creation.
15494     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15495         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15496         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15497
15498         synchronized(this) {
15499             // !!! TODO: currently no check here that we're already bound
15500             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15501             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15502             synchronized (stats) {
15503                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15504             }
15505
15506             // Backup agent is now in use, its package can't be stopped.
15507             try {
15508                 AppGlobals.getPackageManager().setPackageStoppedState(
15509                         app.packageName, false, UserHandle.getUserId(app.uid));
15510             } catch (RemoteException e) {
15511             } catch (IllegalArgumentException e) {
15512                 Slog.w(TAG, "Failed trying to unstop package "
15513                         + app.packageName + ": " + e);
15514             }
15515
15516             BackupRecord r = new BackupRecord(ss, app, backupMode);
15517             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15518                     ? new ComponentName(app.packageName, app.backupAgentName)
15519                     : new ComponentName("android", "FullBackupAgent");
15520             // startProcessLocked() returns existing proc's record if it's already running
15521             ProcessRecord proc = startProcessLocked(app.processName, app,
15522                     false, 0, "backup", hostingName, false, false, false);
15523             if (proc == null) {
15524                 Slog.e(TAG, "Unable to start backup agent process " + r);
15525                 return false;
15526             }
15527
15528             r.app = proc;
15529             mBackupTarget = r;
15530             mBackupAppName = app.packageName;
15531
15532             // Try not to kill the process during backup
15533             updateOomAdjLocked(proc);
15534
15535             // If the process is already attached, schedule the creation of the backup agent now.
15536             // If it is not yet live, this will be done when it attaches to the framework.
15537             if (proc.thread != null) {
15538                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15539                 try {
15540                     proc.thread.scheduleCreateBackupAgent(app,
15541                             compatibilityInfoForPackageLocked(app), backupMode);
15542                 } catch (RemoteException e) {
15543                     // Will time out on the backup manager side
15544                 }
15545             } else {
15546                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15547             }
15548             // Invariants: at this point, the target app process exists and the application
15549             // is either already running or in the process of coming up.  mBackupTarget and
15550             // mBackupAppName describe the app, so that when it binds back to the AM we
15551             // know that it's scheduled for a backup-agent operation.
15552         }
15553         
15554         return true;
15555     }
15556
15557     @Override
15558     public void clearPendingBackup() {
15559         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15560         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15561
15562         synchronized (this) {
15563             mBackupTarget = null;
15564             mBackupAppName = null;
15565         }
15566     }
15567
15568     // A backup agent has just come up
15569     public void backupAgentCreated(String agentPackageName, IBinder agent) {
15570         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15571                 + " = " + agent);
15572
15573         synchronized(this) {
15574             if (!agentPackageName.equals(mBackupAppName)) {
15575                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15576                 return;
15577             }
15578         }
15579
15580         long oldIdent = Binder.clearCallingIdentity();
15581         try {
15582             IBackupManager bm = IBackupManager.Stub.asInterface(
15583                     ServiceManager.getService(Context.BACKUP_SERVICE));
15584             bm.agentConnected(agentPackageName, agent);
15585         } catch (RemoteException e) {
15586             // can't happen; the backup manager service is local
15587         } catch (Exception e) {
15588             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15589             e.printStackTrace();
15590         } finally {
15591             Binder.restoreCallingIdentity(oldIdent);
15592         }
15593     }
15594
15595     // done with this agent
15596     public void unbindBackupAgent(ApplicationInfo appInfo) {
15597         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15598         if (appInfo == null) {
15599             Slog.w(TAG, "unbind backup agent for null app");
15600             return;
15601         }
15602
15603         synchronized(this) {
15604             try {
15605                 if (mBackupAppName == null) {
15606                     Slog.w(TAG, "Unbinding backup agent with no active backup");
15607                     return;
15608                 }
15609
15610                 if (!mBackupAppName.equals(appInfo.packageName)) {
15611                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15612                     return;
15613                 }
15614
15615                 // Not backing this app up any more; reset its OOM adjustment
15616                 final ProcessRecord proc = mBackupTarget.app;
15617                 updateOomAdjLocked(proc);
15618
15619                 // If the app crashed during backup, 'thread' will be null here
15620                 if (proc.thread != null) {
15621                     try {
15622                         proc.thread.scheduleDestroyBackupAgent(appInfo,
15623                                 compatibilityInfoForPackageLocked(appInfo));
15624                     } catch (Exception e) {
15625                         Slog.e(TAG, "Exception when unbinding backup agent:");
15626                         e.printStackTrace();
15627                     }
15628                 }
15629             } finally {
15630                 mBackupTarget = null;
15631                 mBackupAppName = null;
15632             }
15633         }
15634     }
15635     // =========================================================
15636     // BROADCASTS
15637     // =========================================================
15638
15639     boolean isPendingBroadcastProcessLocked(int pid) {
15640         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15641                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15642     }
15643
15644     void skipPendingBroadcastLocked(int pid) {
15645             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15646             for (BroadcastQueue queue : mBroadcastQueues) {
15647                 queue.skipPendingBroadcastLocked(pid);
15648             }
15649     }
15650
15651     // The app just attached; send any pending broadcasts that it should receive
15652     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15653         boolean didSomething = false;
15654         for (BroadcastQueue queue : mBroadcastQueues) {
15655             didSomething |= queue.sendPendingBroadcastsLocked(app);
15656         }
15657         return didSomething;
15658     }
15659
15660     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15661             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15662         enforceNotIsolatedCaller("registerReceiver");
15663         ArrayList<Intent> stickyIntents = null;
15664         ProcessRecord callerApp = null;
15665         int callingUid;
15666         int callingPid;
15667         synchronized(this) {
15668             if (caller != null) {
15669                 callerApp = getRecordForAppLocked(caller);
15670                 if (callerApp == null) {
15671                     throw new SecurityException(
15672                             "Unable to find app for caller " + caller
15673                             + " (pid=" + Binder.getCallingPid()
15674                             + ") when registering receiver " + receiver);
15675                 }
15676                 if (callerApp.info.uid != Process.SYSTEM_UID &&
15677                         !callerApp.pkgList.containsKey(callerPackage) &&
15678                         !"android".equals(callerPackage)) {
15679                     throw new SecurityException("Given caller package " + callerPackage
15680                             + " is not running in process " + callerApp);
15681                 }
15682                 callingUid = callerApp.info.uid;
15683                 callingPid = callerApp.pid;
15684             } else {
15685                 callerPackage = null;
15686                 callingUid = Binder.getCallingUid();
15687                 callingPid = Binder.getCallingPid();
15688             }
15689
15690             userId = handleIncomingUser(callingPid, callingUid, userId,
15691                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15692
15693             Iterator<String> actions = filter.actionsIterator();
15694             if (actions == null) {
15695                 ArrayList<String> noAction = new ArrayList<String>(1);
15696                 noAction.add(null);
15697                 actions = noAction.iterator();
15698             }
15699
15700             // Collect stickies of users
15701             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15702             while (actions.hasNext()) {
15703                 String action = actions.next();
15704                 for (int id : userIds) {
15705                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15706                     if (stickies != null) {
15707                         ArrayList<Intent> intents = stickies.get(action);
15708                         if (intents != null) {
15709                             if (stickyIntents == null) {
15710                                 stickyIntents = new ArrayList<Intent>();
15711                             }
15712                             stickyIntents.addAll(intents);
15713                         }
15714                     }
15715                 }
15716             }
15717         }
15718
15719         ArrayList<Intent> allSticky = null;
15720         if (stickyIntents != null) {
15721             final ContentResolver resolver = mContext.getContentResolver();
15722             // Look for any matching sticky broadcasts...
15723             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15724                 Intent intent = stickyIntents.get(i);
15725                 // If intent has scheme "content", it will need to acccess
15726                 // provider that needs to lock mProviderMap in ActivityThread
15727                 // and also it may need to wait application response, so we
15728                 // cannot lock ActivityManagerService here.
15729                 if (filter.match(resolver, intent, true, TAG) >= 0) {
15730                     if (allSticky == null) {
15731                         allSticky = new ArrayList<Intent>();
15732                     }
15733                     allSticky.add(intent);
15734                 }
15735             }
15736         }
15737
15738         // The first sticky in the list is returned directly back to the client.
15739         Intent sticky = allSticky != null ? allSticky.get(0) : null;
15740         if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
15741         if (receiver == null) {
15742             return sticky;
15743         }
15744
15745         synchronized (this) {
15746             if (callerApp != null && (callerApp.thread == null
15747                     || callerApp.thread.asBinder() != caller.asBinder())) {
15748                 // Original caller already died
15749                 return null;
15750             }
15751             ReceiverList rl
15752                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15753             if (rl == null) {
15754                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15755                         userId, receiver);
15756                 if (rl.app != null) {
15757                     rl.app.receivers.add(rl);
15758                 } else {
15759                     try {
15760                         receiver.asBinder().linkToDeath(rl, 0);
15761                     } catch (RemoteException e) {
15762                         return sticky;
15763                     }
15764                     rl.linkedToDeath = true;
15765                 }
15766                 mRegisteredReceivers.put(receiver.asBinder(), rl);
15767             } else if (rl.uid != callingUid) {
15768                 throw new IllegalArgumentException(
15769                         "Receiver requested to register for uid " + callingUid
15770                         + " was previously registered for uid " + rl.uid);
15771             } else if (rl.pid != callingPid) {
15772                 throw new IllegalArgumentException(
15773                         "Receiver requested to register for pid " + callingPid
15774                         + " was previously registered for pid " + rl.pid);
15775             } else if (rl.userId != userId) {
15776                 throw new IllegalArgumentException(
15777                         "Receiver requested to register for user " + userId
15778                         + " was previously registered for user " + rl.userId);
15779             }
15780             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15781                     permission, callingUid, userId);
15782             rl.add(bf);
15783             if (!bf.debugCheck()) {
15784                 Slog.w(TAG, "==> For Dynamic broadast");
15785             }
15786             mReceiverResolver.addFilter(bf);
15787
15788             // Enqueue broadcasts for all existing stickies that match
15789             // this filter.
15790             if (allSticky != null) {
15791                 ArrayList receivers = new ArrayList();
15792                 receivers.add(bf);
15793
15794                 int N = allSticky.size();
15795                 for (int i=0; i<N; i++) {
15796                     Intent intent = (Intent)allSticky.get(i);
15797                     BroadcastQueue queue = broadcastQueueForIntent(intent);
15798                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15799                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15800                             null, null, false, true, true, -1);
15801                     queue.enqueueParallelBroadcastLocked(r);
15802                     queue.scheduleBroadcastsLocked();
15803                 }
15804             }
15805
15806             return sticky;
15807         }
15808     }
15809
15810     public void unregisterReceiver(IIntentReceiver receiver) {
15811         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15812
15813         final long origId = Binder.clearCallingIdentity();
15814         try {
15815             boolean doTrim = false;
15816
15817             synchronized(this) {
15818                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15819                 if (rl != null) {
15820                     final BroadcastRecord r = rl.curBroadcast;
15821                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15822                         final boolean doNext = r.queue.finishReceiverLocked(
15823                                 r, r.resultCode, r.resultData, r.resultExtras,
15824                                 r.resultAbort, false);
15825                         if (doNext) {
15826                             doTrim = true;
15827                             r.queue.processNextBroadcast(false);
15828                         }
15829                     }
15830
15831                     if (rl.app != null) {
15832                         rl.app.receivers.remove(rl);
15833                     }
15834                     removeReceiverLocked(rl);
15835                     if (rl.linkedToDeath) {
15836                         rl.linkedToDeath = false;
15837                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
15838                     }
15839                 }
15840             }
15841
15842             // If we actually concluded any broadcasts, we might now be able
15843             // to trim the recipients' apps from our working set
15844             if (doTrim) {
15845                 trimApplications();
15846                 return;
15847             }
15848
15849         } finally {
15850             Binder.restoreCallingIdentity(origId);
15851         }
15852     }
15853
15854     void removeReceiverLocked(ReceiverList rl) {
15855         mRegisteredReceivers.remove(rl.receiver.asBinder());
15856         int N = rl.size();
15857         for (int i=0; i<N; i++) {
15858             mReceiverResolver.removeFilter(rl.get(i));
15859         }
15860     }
15861     
15862     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15863         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15864             ProcessRecord r = mLruProcesses.get(i);
15865             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15866                 try {
15867                     r.thread.dispatchPackageBroadcast(cmd, packages);
15868                 } catch (RemoteException ex) {
15869                 }
15870             }
15871         }
15872     }
15873
15874     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15875             int callingUid, int[] users) {
15876         List<ResolveInfo> receivers = null;
15877         try {
15878             HashSet<ComponentName> singleUserReceivers = null;
15879             boolean scannedFirstReceivers = false;
15880             for (int user : users) {
15881                 // Skip users that have Shell restrictions
15882                 if (callingUid == Process.SHELL_UID
15883                         && getUserManagerLocked().hasUserRestriction(
15884                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15885                     continue;
15886                 }
15887                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15888                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15889                 if (user != 0 && newReceivers != null) {
15890                     // If this is not the primary user, we need to check for
15891                     // any receivers that should be filtered out.
15892                     for (int i=0; i<newReceivers.size(); i++) {
15893                         ResolveInfo ri = newReceivers.get(i);
15894                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15895                             newReceivers.remove(i);
15896                             i--;
15897                         }
15898                     }
15899                 }
15900                 if (newReceivers != null && newReceivers.size() == 0) {
15901                     newReceivers = null;
15902                 }
15903                 if (receivers == null) {
15904                     receivers = newReceivers;
15905                 } else if (newReceivers != null) {
15906                     // We need to concatenate the additional receivers
15907                     // found with what we have do far.  This would be easy,
15908                     // but we also need to de-dup any receivers that are
15909                     // singleUser.
15910                     if (!scannedFirstReceivers) {
15911                         // Collect any single user receivers we had already retrieved.
15912                         scannedFirstReceivers = true;
15913                         for (int i=0; i<receivers.size(); i++) {
15914                             ResolveInfo ri = receivers.get(i);
15915                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15916                                 ComponentName cn = new ComponentName(
15917                                         ri.activityInfo.packageName, ri.activityInfo.name);
15918                                 if (singleUserReceivers == null) {
15919                                     singleUserReceivers = new HashSet<ComponentName>();
15920                                 }
15921                                 singleUserReceivers.add(cn);
15922                             }
15923                         }
15924                     }
15925                     // Add the new results to the existing results, tracking
15926                     // and de-dupping single user receivers.
15927                     for (int i=0; i<newReceivers.size(); i++) {
15928                         ResolveInfo ri = newReceivers.get(i);
15929                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15930                             ComponentName cn = new ComponentName(
15931                                     ri.activityInfo.packageName, ri.activityInfo.name);
15932                             if (singleUserReceivers == null) {
15933                                 singleUserReceivers = new HashSet<ComponentName>();
15934                             }
15935                             if (!singleUserReceivers.contains(cn)) {
15936                                 singleUserReceivers.add(cn);
15937                                 receivers.add(ri);
15938                             }
15939                         } else {
15940                             receivers.add(ri);
15941                         }
15942                     }
15943                 }
15944             }
15945         } catch (RemoteException ex) {
15946             // pm is in same process, this will never happen.
15947         }
15948         return receivers;
15949     }
15950
15951     private final int broadcastIntentLocked(ProcessRecord callerApp,
15952             String callerPackage, Intent intent, String resolvedType,
15953             IIntentReceiver resultTo, int resultCode, String resultData,
15954             Bundle map, String requiredPermission, int appOp,
15955             boolean ordered, boolean sticky, int callingPid, int callingUid,
15956             int userId) {
15957         intent = new Intent(intent);
15958
15959         // By default broadcasts do not go to stopped apps.
15960         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15961
15962         if (DEBUG_BROADCAST_LIGHT) Slog.v(
15963             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15964             + " ordered=" + ordered + " userid=" + userId);
15965         if ((resultTo != null) && !ordered) {
15966             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15967         }
15968
15969         userId = handleIncomingUser(callingPid, callingUid, userId,
15970                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15971
15972         // Make sure that the user who is receiving this broadcast is running.
15973         // If not, we will just skip it. Make an exception for shutdown broadcasts
15974         // and upgrade steps.
15975
15976         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15977             if ((callingUid != Process.SYSTEM_UID
15978                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15979                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15980                 Slog.w(TAG, "Skipping broadcast of " + intent
15981                         + ": user " + userId + " is stopped");
15982                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15983             }
15984         }
15985
15986         /*
15987          * Prevent non-system code (defined here to be non-persistent
15988          * processes) from sending protected broadcasts.
15989          */
15990         int callingAppId = UserHandle.getAppId(callingUid);
15991         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15992             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15993             || callingAppId == Process.NFC_UID || callingUid == 0) {
15994             // Always okay.
15995         } else if (callerApp == null || !callerApp.persistent) {
15996             try {
15997                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15998                         intent.getAction())) {
15999                     String msg = "Permission Denial: not allowed to send broadcast "
16000                             + intent.getAction() + " from pid="
16001                             + callingPid + ", uid=" + callingUid;
16002                     Slog.w(TAG, msg);
16003                     throw new SecurityException(msg);
16004                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16005                     // Special case for compatibility: we don't want apps to send this,
16006                     // but historically it has not been protected and apps may be using it
16007                     // to poke their own app widget.  So, instead of making it protected,
16008                     // just limit it to the caller.
16009                     if (callerApp == null) {
16010                         String msg = "Permission Denial: not allowed to send broadcast "
16011                                 + intent.getAction() + " from unknown caller.";
16012                         Slog.w(TAG, msg);
16013                         throw new SecurityException(msg);
16014                     } else if (intent.getComponent() != null) {
16015                         // They are good enough to send to an explicit component...  verify
16016                         // it is being sent to the calling app.
16017                         if (!intent.getComponent().getPackageName().equals(
16018                                 callerApp.info.packageName)) {
16019                             String msg = "Permission Denial: not allowed to send broadcast "
16020                                     + intent.getAction() + " to "
16021                                     + intent.getComponent().getPackageName() + " from "
16022                                     + callerApp.info.packageName;
16023                             Slog.w(TAG, msg);
16024                             throw new SecurityException(msg);
16025                         }
16026                     } else {
16027                         // Limit broadcast to their own package.
16028                         intent.setPackage(callerApp.info.packageName);
16029                     }
16030                 }
16031             } catch (RemoteException e) {
16032                 Slog.w(TAG, "Remote exception", e);
16033                 return ActivityManager.BROADCAST_SUCCESS;
16034             }
16035         }
16036
16037         final String action = intent.getAction();
16038         if (action != null) {
16039             switch (action) {
16040                 case Intent.ACTION_UID_REMOVED:
16041                 case Intent.ACTION_PACKAGE_REMOVED:
16042                 case Intent.ACTION_PACKAGE_CHANGED:
16043                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16044                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16045                     // Handle special intents: if this broadcast is from the package
16046                     // manager about a package being removed, we need to remove all of
16047                     // its activities from the history stack.
16048                     if (checkComponentPermission(
16049                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16050                             callingPid, callingUid, -1, true)
16051                             != PackageManager.PERMISSION_GRANTED) {
16052                         String msg = "Permission Denial: " + intent.getAction()
16053                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16054                                 + ", uid=" + callingUid + ")"
16055                                 + " requires "
16056                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16057                         Slog.w(TAG, msg);
16058                         throw new SecurityException(msg);
16059                     }
16060                     switch (action) {
16061                         case Intent.ACTION_UID_REMOVED:
16062                             final Bundle intentExtras = intent.getExtras();
16063                             final int uid = intentExtras != null
16064                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16065                             if (uid >= 0) {
16066                                 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
16067                                 synchronized (bs) {
16068                                     bs.removeUidStatsLocked(uid);
16069                                 }
16070                                 mAppOpsService.uidRemoved(uid);
16071                             }
16072                             break;
16073                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16074                             // If resources are unavailable just force stop all those packages
16075                             // and flush the attribute cache as well.
16076                             String list[] =
16077                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16078                             if (list != null && list.length > 0) {
16079                                 for (int i = 0; i < list.length; i++) {
16080                                     forceStopPackageLocked(list[i], -1, false, true, true,
16081                                             false, false, userId, "storage unmount");
16082                                 }
16083                                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16084                                 sendPackageBroadcastLocked(
16085                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16086                                         userId);
16087                             }
16088                             break;
16089                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16090                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
16091                             break;
16092                         case Intent.ACTION_PACKAGE_REMOVED:
16093                         case Intent.ACTION_PACKAGE_CHANGED:
16094                             Uri data = intent.getData();
16095                             String ssp;
16096                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16097                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16098                                 boolean fullUninstall = removed &&
16099                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16100                                 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16101                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16102                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16103                                             false, true, true, false, fullUninstall, userId,
16104                                             removed ? "pkg removed" : "pkg changed");
16105                                 }
16106                                 if (removed) {
16107                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16108                                             new String[] {ssp}, userId);
16109                                     if (fullUninstall) {
16110                                         mAppOpsService.packageRemoved(
16111                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16112
16113                                         // Remove all permissions granted from/to this package
16114                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16115
16116                                         removeTasksByPackageNameLocked(ssp, userId);
16117                                         if (userId == UserHandle.USER_OWNER) {
16118                                             mTaskPersister.removeFromPackageCache(ssp);
16119                                         }
16120                                     }
16121                                 } else {
16122                                     removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16123                                     if (userId == UserHandle.USER_OWNER) {
16124                                         mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16125                                     }
16126                                 }
16127                             }
16128                             break;
16129                     }
16130                     break;
16131                 case Intent.ACTION_PACKAGE_ADDED:
16132                     // Special case for adding a package: by default turn on compatibility mode.
16133                     Uri data = intent.getData();
16134                     String ssp;
16135                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16136                         final boolean replacing =
16137                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16138                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16139
16140                         if (replacing) {
16141                             removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16142                         }
16143                         if (userId == UserHandle.USER_OWNER) {
16144                             mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16145                         }
16146                     }
16147                     break;
16148                 case Intent.ACTION_TIMEZONE_CHANGED:
16149                     // If this is the time zone changed action, queue up a message that will reset
16150                     // the timezone of all currently running processes. This message will get
16151                     // queued up before the broadcast happens.
16152                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16153                     break;
16154                 case Intent.ACTION_TIME_CHANGED:
16155                     // If the user set the time, let all running processes know.
16156                     final int is24Hour =
16157                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16158                                     : 0;
16159                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16160                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16161                     synchronized (stats) {
16162                         stats.noteCurrentTimeChangedLocked();
16163                     }
16164                     break;
16165                 case Intent.ACTION_CLEAR_DNS_CACHE:
16166                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16167                     break;
16168                 case Proxy.PROXY_CHANGE_ACTION:
16169                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16170                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16171                     break;
16172             }
16173         }
16174
16175         // Add to the sticky list if requested.
16176         if (sticky) {
16177             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16178                     callingPid, callingUid)
16179                     != PackageManager.PERMISSION_GRANTED) {
16180                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16181                         + callingPid + ", uid=" + callingUid
16182                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16183                 Slog.w(TAG, msg);
16184                 throw new SecurityException(msg);
16185             }
16186             if (requiredPermission != null) {
16187                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16188                         + " and enforce permission " + requiredPermission);
16189                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16190             }
16191             if (intent.getComponent() != null) {
16192                 throw new SecurityException(
16193                         "Sticky broadcasts can't target a specific component");
16194             }
16195             // We use userId directly here, since the "all" target is maintained
16196             // as a separate set of sticky broadcasts.
16197             if (userId != UserHandle.USER_ALL) {
16198                 // But first, if this is not a broadcast to all users, then
16199                 // make sure it doesn't conflict with an existing broadcast to
16200                 // all users.
16201                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16202                         UserHandle.USER_ALL);
16203                 if (stickies != null) {
16204                     ArrayList<Intent> list = stickies.get(intent.getAction());
16205                     if (list != null) {
16206                         int N = list.size();
16207                         int i;
16208                         for (i=0; i<N; i++) {
16209                             if (intent.filterEquals(list.get(i))) {
16210                                 throw new IllegalArgumentException(
16211                                         "Sticky broadcast " + intent + " for user "
16212                                         + userId + " conflicts with existing global broadcast");
16213                             }
16214                         }
16215                     }
16216                 }
16217             }
16218             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16219             if (stickies == null) {
16220                 stickies = new ArrayMap<String, ArrayList<Intent>>();
16221                 mStickyBroadcasts.put(userId, stickies);
16222             }
16223             ArrayList<Intent> list = stickies.get(intent.getAction());
16224             if (list == null) {
16225                 list = new ArrayList<Intent>();
16226                 stickies.put(intent.getAction(), list);
16227             }
16228             int N = list.size();
16229             int i;
16230             for (i=0; i<N; i++) {
16231                 if (intent.filterEquals(list.get(i))) {
16232                     // This sticky already exists, replace it.
16233                     list.set(i, new Intent(intent));
16234                     break;
16235                 }
16236             }
16237             if (i >= N) {
16238                 list.add(new Intent(intent));
16239             }
16240         }
16241
16242         int[] users;
16243         if (userId == UserHandle.USER_ALL) {
16244             // Caller wants broadcast to go to all started users.
16245             users = mStartedUserArray;
16246         } else {
16247             // Caller wants broadcast to go to one specific user.
16248             users = new int[] {userId};
16249         }
16250
16251         // Figure out who all will receive this broadcast.
16252         List receivers = null;
16253         List<BroadcastFilter> registeredReceivers = null;
16254         // Need to resolve the intent to interested receivers...
16255         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16256                  == 0) {
16257             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16258         }
16259         if (intent.getComponent() == null) {
16260             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16261                 // Query one target user at a time, excluding shell-restricted users
16262                 UserManagerService ums = getUserManagerLocked();
16263                 for (int i = 0; i < users.length; i++) {
16264                     if (ums.hasUserRestriction(
16265                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16266                         continue;
16267                     }
16268                     List<BroadcastFilter> registeredReceiversForUser =
16269                             mReceiverResolver.queryIntent(intent,
16270                                     resolvedType, false, users[i]);
16271                     if (registeredReceivers == null) {
16272                         registeredReceivers = registeredReceiversForUser;
16273                     } else if (registeredReceiversForUser != null) {
16274                         registeredReceivers.addAll(registeredReceiversForUser);
16275                     }
16276                 }
16277             } else {
16278                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16279                         resolvedType, false, userId);
16280             }
16281         }
16282
16283         final boolean replacePending =
16284                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16285         
16286         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16287                 + " replacePending=" + replacePending);
16288         
16289         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16290         if (!ordered && NR > 0) {
16291             // If we are not serializing this broadcast, then send the
16292             // registered receivers separately so they don't wait for the
16293             // components to be launched.
16294             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16295             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16296                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16297                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16298                     ordered, sticky, false, userId);
16299             if (DEBUG_BROADCAST) Slog.v(
16300                     TAG, "Enqueueing parallel broadcast " + r);
16301             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16302             if (!replaced) {
16303                 queue.enqueueParallelBroadcastLocked(r);
16304                 queue.scheduleBroadcastsLocked();
16305             }
16306             registeredReceivers = null;
16307             NR = 0;
16308         }
16309
16310         // Merge into one list.
16311         int ir = 0;
16312         if (receivers != null) {
16313             // A special case for PACKAGE_ADDED: do not allow the package
16314             // being added to see this broadcast.  This prevents them from
16315             // using this as a back door to get run as soon as they are
16316             // installed.  Maybe in the future we want to have a special install
16317             // broadcast or such for apps, but we'd like to deliberately make
16318             // this decision.
16319             String skipPackages[] = null;
16320             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16321                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16322                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16323                 Uri data = intent.getData();
16324                 if (data != null) {
16325                     String pkgName = data.getSchemeSpecificPart();
16326                     if (pkgName != null) {
16327                         skipPackages = new String[] { pkgName };
16328                     }
16329                 }
16330             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16331                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16332             }
16333             if (skipPackages != null && (skipPackages.length > 0)) {
16334                 for (String skipPackage : skipPackages) {
16335                     if (skipPackage != null) {
16336                         int NT = receivers.size();
16337                         for (int it=0; it<NT; it++) {
16338                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
16339                             if (curt.activityInfo.packageName.equals(skipPackage)) {
16340                                 receivers.remove(it);
16341                                 it--;
16342                                 NT--;
16343                             }
16344                         }
16345                     }
16346                 }
16347             }
16348
16349             int NT = receivers != null ? receivers.size() : 0;
16350             int it = 0;
16351             ResolveInfo curt = null;
16352             BroadcastFilter curr = null;
16353             while (it < NT && ir < NR) {
16354                 if (curt == null) {
16355                     curt = (ResolveInfo)receivers.get(it);
16356                 }
16357                 if (curr == null) {
16358                     curr = registeredReceivers.get(ir);
16359                 }
16360                 if (curr.getPriority() >= curt.priority) {
16361                     // Insert this broadcast record into the final list.
16362                     receivers.add(it, curr);
16363                     ir++;
16364                     curr = null;
16365                     it++;
16366                     NT++;
16367                 } else {
16368                     // Skip to the next ResolveInfo in the final list.
16369                     it++;
16370                     curt = null;
16371                 }
16372             }
16373         }
16374         while (ir < NR) {
16375             if (receivers == null) {
16376                 receivers = new ArrayList();
16377             }
16378             receivers.add(registeredReceivers.get(ir));
16379             ir++;
16380         }
16381
16382         if ((receivers != null && receivers.size() > 0)
16383                 || resultTo != null) {
16384             BroadcastQueue queue = broadcastQueueForIntent(intent);
16385             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16386                     callerPackage, callingPid, callingUid, resolvedType,
16387                     requiredPermission, appOp, receivers, resultTo, resultCode,
16388                     resultData, map, ordered, sticky, false, userId);
16389             if (DEBUG_BROADCAST) Slog.v(
16390                     TAG, "Enqueueing ordered broadcast " + r
16391                     + ": prev had " + queue.mOrderedBroadcasts.size());
16392             if (DEBUG_BROADCAST) {
16393                 int seq = r.intent.getIntExtra("seq", -1);
16394                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16395             }
16396             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
16397             if (!replaced) {
16398                 queue.enqueueOrderedBroadcastLocked(r);
16399                 queue.scheduleBroadcastsLocked();
16400             }
16401         }
16402
16403         return ActivityManager.BROADCAST_SUCCESS;
16404     }
16405
16406     final Intent verifyBroadcastLocked(Intent intent) {
16407         // Refuse possible leaked file descriptors
16408         if (intent != null && intent.hasFileDescriptors() == true) {
16409             throw new IllegalArgumentException("File descriptors passed in Intent");
16410         }
16411
16412         int flags = intent.getFlags();
16413
16414         if (!mProcessesReady) {
16415             // if the caller really truly claims to know what they're doing, go
16416             // ahead and allow the broadcast without launching any receivers
16417             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16418                 intent = new Intent(intent);
16419                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16420             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16421                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16422                         + " before boot completion");
16423                 throw new IllegalStateException("Cannot broadcast before boot completed");
16424             }
16425         }
16426
16427         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16428             throw new IllegalArgumentException(
16429                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16430         }
16431
16432         return intent;
16433     }
16434
16435     public final int broadcastIntent(IApplicationThread caller,
16436             Intent intent, String resolvedType, IIntentReceiver resultTo,
16437             int resultCode, String resultData, Bundle map,
16438             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16439         enforceNotIsolatedCaller("broadcastIntent");
16440         synchronized(this) {
16441             intent = verifyBroadcastLocked(intent);
16442
16443             final ProcessRecord callerApp = getRecordForAppLocked(caller);
16444             final int callingPid = Binder.getCallingPid();
16445             final int callingUid = Binder.getCallingUid();
16446             final long origId = Binder.clearCallingIdentity();
16447             int res = broadcastIntentLocked(callerApp,
16448                     callerApp != null ? callerApp.info.packageName : null,
16449                     intent, resolvedType, resultTo,
16450                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16451                     callingPid, callingUid, userId);
16452             Binder.restoreCallingIdentity(origId);
16453             return res;
16454         }
16455     }
16456
16457     int broadcastIntentInPackage(String packageName, int uid,
16458             Intent intent, String resolvedType, IIntentReceiver resultTo,
16459             int resultCode, String resultData, Bundle map,
16460             String requiredPermission, boolean serialized, boolean sticky, int userId) {
16461         synchronized(this) {
16462             intent = verifyBroadcastLocked(intent);
16463
16464             final long origId = Binder.clearCallingIdentity();
16465             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16466                     resultTo, resultCode, resultData, map, requiredPermission,
16467                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16468             Binder.restoreCallingIdentity(origId);
16469             return res;
16470         }
16471     }
16472
16473     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16474         // Refuse possible leaked file descriptors
16475         if (intent != null && intent.hasFileDescriptors() == true) {
16476             throw new IllegalArgumentException("File descriptors passed in Intent");
16477         }
16478
16479         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16480                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16481
16482         synchronized(this) {
16483             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16484                     != PackageManager.PERMISSION_GRANTED) {
16485                 String msg = "Permission Denial: unbroadcastIntent() from pid="
16486                         + Binder.getCallingPid()
16487                         + ", uid=" + Binder.getCallingUid()
16488                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16489                 Slog.w(TAG, msg);
16490                 throw new SecurityException(msg);
16491             }
16492             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16493             if (stickies != null) {
16494                 ArrayList<Intent> list = stickies.get(intent.getAction());
16495                 if (list != null) {
16496                     int N = list.size();
16497                     int i;
16498                     for (i=0; i<N; i++) {
16499                         if (intent.filterEquals(list.get(i))) {
16500                             list.remove(i);
16501                             break;
16502                         }
16503                     }
16504                     if (list.size() <= 0) {
16505                         stickies.remove(intent.getAction());
16506                     }
16507                 }
16508                 if (stickies.size() <= 0) {
16509                     mStickyBroadcasts.remove(userId);
16510                 }
16511             }
16512         }
16513     }
16514
16515     void backgroundServicesFinishedLocked(int userId) {
16516         for (BroadcastQueue queue : mBroadcastQueues) {
16517             queue.backgroundServicesFinishedLocked(userId);
16518         }
16519     }
16520
16521     public void finishReceiver(IBinder who, int resultCode, String resultData,
16522             Bundle resultExtras, boolean resultAbort, int flags) {
16523         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16524
16525         // Refuse possible leaked file descriptors
16526         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16527             throw new IllegalArgumentException("File descriptors passed in Bundle");
16528         }
16529
16530         final long origId = Binder.clearCallingIdentity();
16531         try {
16532             boolean doNext = false;
16533             BroadcastRecord r;
16534
16535             synchronized(this) {
16536                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16537                         ? mFgBroadcastQueue : mBgBroadcastQueue;
16538                 r = queue.getMatchingOrderedReceiver(who);
16539                 if (r != null) {
16540                     doNext = r.queue.finishReceiverLocked(r, resultCode,
16541                         resultData, resultExtras, resultAbort, true);
16542                 }
16543             }
16544
16545             if (doNext) {
16546                 r.queue.processNextBroadcast(false);
16547             }
16548             trimApplications();
16549         } finally {
16550             Binder.restoreCallingIdentity(origId);
16551         }
16552     }
16553     
16554     // =========================================================
16555     // INSTRUMENTATION
16556     // =========================================================
16557
16558     public boolean startInstrumentation(ComponentName className,
16559             String profileFile, int flags, Bundle arguments,
16560             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16561             int userId, String abiOverride) {
16562         enforceNotIsolatedCaller("startInstrumentation");
16563         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16564                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16565         // Refuse possible leaked file descriptors
16566         if (arguments != null && arguments.hasFileDescriptors()) {
16567             throw new IllegalArgumentException("File descriptors passed in Bundle");
16568         }
16569
16570         synchronized(this) {
16571             InstrumentationInfo ii = null;
16572             ApplicationInfo ai = null;
16573             try {
16574                 ii = mContext.getPackageManager().getInstrumentationInfo(
16575                     className, STOCK_PM_FLAGS);
16576                 ai = AppGlobals.getPackageManager().getApplicationInfo(
16577                         ii.targetPackage, STOCK_PM_FLAGS, userId);
16578             } catch (PackageManager.NameNotFoundException e) {
16579             } catch (RemoteException e) {
16580             }
16581             if (ii == null) {
16582                 reportStartInstrumentationFailure(watcher, className,
16583                         "Unable to find instrumentation info for: " + className);
16584                 return false;
16585             }
16586             if (ai == null) {
16587                 reportStartInstrumentationFailure(watcher, className,
16588                         "Unable to find instrumentation target package: " + ii.targetPackage);
16589                 return false;
16590             }
16591
16592             int match = mContext.getPackageManager().checkSignatures(
16593                     ii.targetPackage, ii.packageName);
16594             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16595                 String msg = "Permission Denial: starting instrumentation "
16596                         + className + " from pid="
16597                         + Binder.getCallingPid()
16598                         + ", uid=" + Binder.getCallingPid()
16599                         + " not allowed because package " + ii.packageName
16600                         + " does not have a signature matching the target "
16601                         + ii.targetPackage;
16602                 reportStartInstrumentationFailure(watcher, className, msg);
16603                 throw new SecurityException(msg);
16604             }
16605
16606             final long origId = Binder.clearCallingIdentity();
16607             // Instrumentation can kill and relaunch even persistent processes
16608             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16609                     "start instr");
16610             ProcessRecord app = addAppLocked(ai, false, abiOverride);
16611             app.instrumentationClass = className;
16612             app.instrumentationInfo = ai;
16613             app.instrumentationProfileFile = profileFile;
16614             app.instrumentationArguments = arguments;
16615             app.instrumentationWatcher = watcher;
16616             app.instrumentationUiAutomationConnection = uiAutomationConnection;
16617             app.instrumentationResultClass = className;
16618             Binder.restoreCallingIdentity(origId);
16619         }
16620
16621         return true;
16622     }
16623     
16624     /**
16625      * Report errors that occur while attempting to start Instrumentation.  Always writes the 
16626      * error to the logs, but if somebody is watching, send the report there too.  This enables
16627      * the "am" command to report errors with more information.
16628      * 
16629      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16630      * @param cn The component name of the instrumentation.
16631      * @param report The error report.
16632      */
16633     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 
16634             ComponentName cn, String report) {
16635         Slog.w(TAG, report);
16636         try {
16637             if (watcher != null) {
16638                 Bundle results = new Bundle();
16639                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16640                 results.putString("Error", report);
16641                 watcher.instrumentationStatus(cn, -1, results);
16642             }
16643         } catch (RemoteException e) {
16644             Slog.w(TAG, e);
16645         }
16646     }
16647
16648     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16649         if (app.instrumentationWatcher != null) {
16650             try {
16651                 // NOTE:  IInstrumentationWatcher *must* be oneway here
16652                 app.instrumentationWatcher.instrumentationFinished(
16653                     app.instrumentationClass,
16654                     resultCode,
16655                     results);
16656             } catch (RemoteException e) {
16657             }
16658         }
16659         if (app.instrumentationUiAutomationConnection != null) {
16660             try {
16661                 app.instrumentationUiAutomationConnection.shutdown();
16662             } catch (RemoteException re) {
16663                 /* ignore */
16664             }
16665             // Only a UiAutomation can set this flag and now that
16666             // it is finished we make sure it is reset to its default.
16667             mUserIsMonkey = false;
16668         }
16669         app.instrumentationWatcher = null;
16670         app.instrumentationUiAutomationConnection = null;
16671         app.instrumentationClass = null;
16672         app.instrumentationInfo = null;
16673         app.instrumentationProfileFile = null;
16674         app.instrumentationArguments = null;
16675
16676         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16677                 "finished inst");
16678     }
16679
16680     public void finishInstrumentation(IApplicationThread target,
16681             int resultCode, Bundle results) {
16682         int userId = UserHandle.getCallingUserId();
16683         // Refuse possible leaked file descriptors
16684         if (results != null && results.hasFileDescriptors()) {
16685             throw new IllegalArgumentException("File descriptors passed in Intent");
16686         }
16687
16688         synchronized(this) {
16689             ProcessRecord app = getRecordForAppLocked(target);
16690             if (app == null) {
16691                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16692                 return;
16693             }
16694             final long origId = Binder.clearCallingIdentity();
16695             finishInstrumentationLocked(app, resultCode, results);
16696             Binder.restoreCallingIdentity(origId);
16697         }
16698     }
16699
16700     // =========================================================
16701     // CONFIGURATION
16702     // =========================================================
16703     
16704     public ConfigurationInfo getDeviceConfigurationInfo() {
16705         ConfigurationInfo config = new ConfigurationInfo();
16706         synchronized (this) {
16707             config.reqTouchScreen = mConfiguration.touchscreen;
16708             config.reqKeyboardType = mConfiguration.keyboard;
16709             config.reqNavigation = mConfiguration.navigation;
16710             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16711                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16712                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16713             }
16714             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16715                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16716                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16717             }
16718             config.reqGlEsVersion = GL_ES_VERSION;
16719         }
16720         return config;
16721     }
16722
16723     ActivityStack getFocusedStack() {
16724         return mStackSupervisor.getFocusedStack();
16725     }
16726
16727     public Configuration getConfiguration() {
16728         Configuration ci;
16729         synchronized(this) {
16730             ci = new Configuration(mConfiguration);
16731             ci.userSetLocale = false;
16732         }
16733         return ci;
16734     }
16735
16736     public void updatePersistentConfiguration(Configuration values) {
16737         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16738                 "updateConfiguration()");
16739         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16740                 "updateConfiguration()");
16741         if (values == null) {
16742             throw new NullPointerException("Configuration must not be null");
16743         }
16744
16745         synchronized(this) {
16746             final long origId = Binder.clearCallingIdentity();
16747             updateConfigurationLocked(values, null, true, false);
16748             Binder.restoreCallingIdentity(origId);
16749         }
16750     }
16751
16752     public void updateConfiguration(Configuration values) {
16753         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16754                 "updateConfiguration()");
16755
16756         synchronized(this) {
16757             if (values == null && mWindowManager != null) {
16758                 // sentinel: fetch the current configuration from the window manager
16759                 values = mWindowManager.computeNewConfiguration();
16760             }
16761
16762             if (mWindowManager != null) {
16763                 mProcessList.applyDisplaySize(mWindowManager);
16764             }
16765
16766             final long origId = Binder.clearCallingIdentity();
16767             if (values != null) {
16768                 Settings.System.clearConfiguration(values);
16769             }
16770             updateConfigurationLocked(values, null, false, false);
16771             Binder.restoreCallingIdentity(origId);
16772         }
16773     }
16774
16775     /**
16776      * Do either or both things: (1) change the current configuration, and (2)
16777      * make sure the given activity is running with the (now) current
16778      * configuration.  Returns true if the activity has been left running, or
16779      * false if <var>starting</var> is being destroyed to match the new
16780      * configuration.
16781      * @param persistent TODO
16782      */
16783     boolean updateConfigurationLocked(Configuration values,
16784             ActivityRecord starting, boolean persistent, boolean initLocale) {
16785         int changes = 0;
16786
16787         if (values != null) {
16788             Configuration newConfig = new Configuration(mConfiguration);
16789             changes = newConfig.updateFrom(values);
16790             if (changes != 0) {
16791                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16792                     Slog.i(TAG, "Updating configuration to: " + values);
16793                 }
16794                 
16795                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16796
16797                 if (!initLocale && values.locale != null && values.userSetLocale) {
16798                     final String languageTag = values.locale.toLanguageTag();
16799                     SystemProperties.set("persist.sys.locale", languageTag);
16800                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16801                             values.locale));
16802                 }
16803
16804                 mConfigurationSeq++;
16805                 if (mConfigurationSeq <= 0) {
16806                     mConfigurationSeq = 1;
16807                 }
16808                 newConfig.seq = mConfigurationSeq;
16809                 mConfiguration = newConfig;
16810                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16811                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16812                 //mUsageStatsService.noteStartConfig(newConfig);
16813
16814                 final Configuration configCopy = new Configuration(mConfiguration);
16815                 
16816                 // TODO: If our config changes, should we auto dismiss any currently
16817                 // showing dialogs?
16818                 mShowDialogs = shouldShowDialogs(newConfig);
16819
16820                 AttributeCache ac = AttributeCache.instance();
16821                 if (ac != null) {
16822                     ac.updateConfiguration(configCopy);
16823                 }
16824
16825                 // Make sure all resources in our process are updated
16826                 // right now, so that anyone who is going to retrieve
16827                 // resource values after we return will be sure to get
16828                 // the new ones.  This is especially important during
16829                 // boot, where the first config change needs to guarantee
16830                 // all resources have that config before following boot
16831                 // code is executed.
16832                 mSystemThread.applyConfigurationToResources(configCopy);
16833
16834                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16835                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16836                     msg.obj = new Configuration(configCopy);
16837                     mHandler.sendMessage(msg);
16838                 }
16839
16840                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16841                     ProcessRecord app = mLruProcesses.get(i);
16842                     try {
16843                         if (app.thread != null) {
16844                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16845                                     + app.processName + " new config " + mConfiguration);
16846                             app.thread.scheduleConfigurationChanged(configCopy);
16847                         }
16848                     } catch (Exception e) {
16849                     }
16850                 }
16851                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16852                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16853                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
16854                         | Intent.FLAG_RECEIVER_FOREGROUND);
16855                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16856                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
16857                         Process.SYSTEM_UID, UserHandle.USER_ALL);
16858                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16859                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16860                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16861                     if (!mProcessesReady) {
16862                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16863                     }
16864                     broadcastIntentLocked(null, null, intent,
16865                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16866                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16867                 }
16868             }
16869         }
16870
16871         boolean kept = true;
16872         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16873         // mainStack is null during startup.
16874         if (mainStack != null) {
16875             if (changes != 0 && starting == null) {
16876                 // If the configuration changed, and the caller is not already
16877                 // in the process of starting an activity, then find the top
16878                 // activity to check if its configuration needs to change.
16879                 starting = mainStack.topRunningActivityLocked(null);
16880             }
16881
16882             if (starting != null) {
16883                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16884                 // And we need to make sure at this point that all other activities
16885                 // are made visible with the correct configuration.
16886                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16887             }
16888         }
16889
16890         if (values != null && mWindowManager != null) {
16891             mWindowManager.setNewConfiguration(mConfiguration);
16892         }
16893
16894         return kept;
16895     }
16896
16897     /**
16898      * Decide based on the configuration whether we should shouw the ANR,
16899      * crash, etc dialogs.  The idea is that if there is no affordnace to
16900      * press the on-screen buttons, we shouldn't show the dialog.
16901      *
16902      * A thought: SystemUI might also want to get told about this, the Power
16903      * dialog / global actions also might want different behaviors.
16904      */
16905     private static final boolean shouldShowDialogs(Configuration config) {
16906         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16907                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16908     }
16909
16910     @Override
16911     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16912         synchronized (this) {
16913             ActivityRecord srec = ActivityRecord.forToken(token);
16914             if (srec.task != null && srec.task.stack != null) {
16915                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16916             }
16917         }
16918         return false;
16919     }
16920
16921     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16922             Intent resultData) {
16923
16924         synchronized (this) {
16925             final ActivityStack stack = ActivityRecord.getStackLocked(token);
16926             if (stack != null) {
16927                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16928             }
16929             return false;
16930         }
16931     }
16932
16933     public int getLaunchedFromUid(IBinder activityToken) {
16934         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16935         if (srec == null) {
16936             return -1;
16937         }
16938         return srec.launchedFromUid;
16939     }
16940
16941     public String getLaunchedFromPackage(IBinder activityToken) {
16942         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16943         if (srec == null) {
16944             return null;
16945         }
16946         return srec.launchedFromPackage;
16947     }
16948
16949     // =========================================================
16950     // LIFETIME MANAGEMENT
16951     // =========================================================
16952
16953     // Returns which broadcast queue the app is the current [or imminent] receiver
16954     // on, or 'null' if the app is not an active broadcast recipient.
16955     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16956         BroadcastRecord r = app.curReceiver;
16957         if (r != null) {
16958             return r.queue;
16959         }
16960
16961         // It's not the current receiver, but it might be starting up to become one
16962         synchronized (this) {
16963             for (BroadcastQueue queue : mBroadcastQueues) {
16964                 r = queue.mPendingBroadcast;
16965                 if (r != null && r.curApp == app) {
16966                     // found it; report which queue it's in
16967                     return queue;
16968                 }
16969             }
16970         }
16971
16972         return null;
16973     }
16974
16975     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16976             ComponentName targetComponent, String targetProcess) {
16977         if (!mTrackingAssociations) {
16978             return null;
16979         }
16980         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16981                 = mAssociations.get(targetUid);
16982         if (components == null) {
16983             components = new ArrayMap<>();
16984             mAssociations.put(targetUid, components);
16985         }
16986         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16987         if (sourceUids == null) {
16988             sourceUids = new SparseArray<>();
16989             components.put(targetComponent, sourceUids);
16990         }
16991         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16992         if (sourceProcesses == null) {
16993             sourceProcesses = new ArrayMap<>();
16994             sourceUids.put(sourceUid, sourceProcesses);
16995         }
16996         Association ass = sourceProcesses.get(sourceProcess);
16997         if (ass == null) {
16998             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
16999                     targetProcess);
17000             sourceProcesses.put(sourceProcess, ass);
17001         }
17002         ass.mCount++;
17003         ass.mNesting++;
17004         if (ass.mNesting == 1) {
17005             ass.mStartTime = SystemClock.uptimeMillis();
17006         }
17007         return ass;
17008     }
17009
17010     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17011             ComponentName targetComponent) {
17012         if (!mTrackingAssociations) {
17013             return;
17014         }
17015         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17016                 = mAssociations.get(targetUid);
17017         if (components == null) {
17018             return;
17019         }
17020         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17021         if (sourceUids == null) {
17022             return;
17023         }
17024         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17025         if (sourceProcesses == null) {
17026             return;
17027         }
17028         Association ass = sourceProcesses.get(sourceProcess);
17029         if (ass == null || ass.mNesting <= 0) {
17030             return;
17031         }
17032         ass.mNesting--;
17033         if (ass.mNesting == 0) {
17034             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17035         }
17036     }
17037
17038     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17039             boolean doingAll, long now) {
17040         if (mAdjSeq == app.adjSeq) {
17041             // This adjustment has already been computed.
17042             return app.curRawAdj;
17043         }
17044
17045         if (app.thread == null) {
17046             app.adjSeq = mAdjSeq;
17047             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17048             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17049             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17050         }
17051
17052         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17053         app.adjSource = null;
17054         app.adjTarget = null;
17055         app.empty = false;
17056         app.cached = false;
17057
17058         final int activitiesSize = app.activities.size();
17059
17060         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17061             // The max adjustment doesn't allow this app to be anything
17062             // below foreground, so it is not worth doing work for it.
17063             app.adjType = "fixed";
17064             app.adjSeq = mAdjSeq;
17065             app.curRawAdj = app.maxAdj;
17066             app.foregroundActivities = false;
17067             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17068             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17069             // System processes can do UI, and when they do we want to have
17070             // them trim their memory after the user leaves the UI.  To
17071             // facilitate this, here we need to determine whether or not it
17072             // is currently showing UI.
17073             app.systemNoUi = true;
17074             if (app == TOP_APP) {
17075                 app.systemNoUi = false;
17076             } else if (activitiesSize > 0) {
17077                 for (int j = 0; j < activitiesSize; j++) {
17078                     final ActivityRecord r = app.activities.get(j);
17079                     if (r.visible) {
17080                         app.systemNoUi = false;
17081                     }
17082                 }
17083             }
17084             if (!app.systemNoUi) {
17085                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17086             }
17087             return (app.curAdj=app.maxAdj);
17088         }
17089
17090         app.systemNoUi = false;
17091
17092         // Determine the importance of the process, starting with most
17093         // important to least, and assign an appropriate OOM adjustment.
17094         int adj;
17095         int schedGroup;
17096         int procState;
17097         boolean foregroundActivities = false;
17098         BroadcastQueue queue;
17099         if (app == TOP_APP) {
17100             // The last app on the list is the foreground app.
17101             adj = ProcessList.FOREGROUND_APP_ADJ;
17102             schedGroup = Process.THREAD_GROUP_DEFAULT;
17103             app.adjType = "top-activity";
17104             foregroundActivities = true;
17105             procState = ActivityManager.PROCESS_STATE_TOP;
17106         } else if (app.instrumentationClass != null) {
17107             // Don't want to kill running instrumentation.
17108             adj = ProcessList.FOREGROUND_APP_ADJ;
17109             schedGroup = Process.THREAD_GROUP_DEFAULT;
17110             app.adjType = "instrumentation";
17111             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17112         } else if ((queue = isReceivingBroadcast(app)) != null) {
17113             // An app that is currently receiving a broadcast also
17114             // counts as being in the foreground for OOM killer purposes.
17115             // It's placed in a sched group based on the nature of the
17116             // broadcast as reflected by which queue it's active in.
17117             adj = ProcessList.FOREGROUND_APP_ADJ;
17118             schedGroup = (queue == mFgBroadcastQueue)
17119                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17120             app.adjType = "broadcast";
17121             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17122         } else if (app.executingServices.size() > 0) {
17123             // An app that is currently executing a service callback also
17124             // counts as being in the foreground.
17125             adj = ProcessList.FOREGROUND_APP_ADJ;
17126             schedGroup = app.execServicesFg ?
17127                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17128             app.adjType = "exec-service";
17129             procState = ActivityManager.PROCESS_STATE_SERVICE;
17130             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17131         } else {
17132             // As far as we know the process is empty.  We may change our mind later.
17133             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17134             // At this point we don't actually know the adjustment.  Use the cached adj
17135             // value that the caller wants us to.
17136             adj = cachedAdj;
17137             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17138             app.cached = true;
17139             app.empty = true;
17140             app.adjType = "cch-empty";
17141         }
17142
17143         // Examine all activities if not already foreground.
17144         if (!foregroundActivities && activitiesSize > 0) {
17145             for (int j = 0; j < activitiesSize; j++) {
17146                 final ActivityRecord r = app.activities.get(j);
17147                 if (r.app != app) {
17148                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17149                             + app + "?!?");
17150                     continue;
17151                 }
17152                 if (r.visible) {
17153                     // App has a visible activity; only upgrade adjustment.
17154                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17155                         adj = ProcessList.VISIBLE_APP_ADJ;
17156                         app.adjType = "visible";
17157                     }
17158                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
17159                         procState = ActivityManager.PROCESS_STATE_TOP;
17160                     }
17161                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17162                     app.cached = false;
17163                     app.empty = false;
17164                     foregroundActivities = true;
17165                     break;
17166                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17167                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17168                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17169                         app.adjType = "pausing";
17170                     }
17171                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
17172                         procState = ActivityManager.PROCESS_STATE_TOP;
17173                     }
17174                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17175                     app.cached = false;
17176                     app.empty = false;
17177                     foregroundActivities = true;
17178                 } else if (r.state == ActivityState.STOPPING) {
17179                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17180                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17181                         app.adjType = "stopping";
17182                     }
17183                     // For the process state, we will at this point consider the
17184                     // process to be cached.  It will be cached either as an activity
17185                     // or empty depending on whether the activity is finishing.  We do
17186                     // this so that we can treat the process as cached for purposes of
17187                     // memory trimming (determing current memory level, trim command to
17188                     // send to process) since there can be an arbitrary number of stopping
17189                     // processes and they should soon all go into the cached state.
17190                     if (!r.finishing) {
17191                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17192                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17193                         }
17194                     }
17195                     app.cached = false;
17196                     app.empty = false;
17197                     foregroundActivities = true;
17198                 } else {
17199                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17200                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17201                         app.adjType = "cch-act";
17202                     }
17203                 }
17204             }
17205         }
17206
17207         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17208             if (app.foregroundServices) {
17209                 // The user is aware of this app, so make it visible.
17210                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17211                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17212                 app.cached = false;
17213                 app.adjType = "fg-service";
17214                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17215             } else if (app.forcingToForeground != null) {
17216                 // The user is aware of this app, so make it visible.
17217                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17218                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17219                 app.cached = false;
17220                 app.adjType = "force-fg";
17221                 app.adjSource = app.forcingToForeground;
17222                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17223             }
17224         }
17225
17226         if (app == mHeavyWeightProcess) {
17227             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17228                 // We don't want to kill the current heavy-weight process.
17229                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17230                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17231                 app.cached = false;
17232                 app.adjType = "heavy";
17233             }
17234             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17235                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17236             }
17237         }
17238
17239         if (app == mHomeProcess) {
17240             if (adj > ProcessList.HOME_APP_ADJ) {
17241                 // This process is hosting what we currently consider to be the
17242                 // home app, so we don't want to let it go into the background.
17243                 adj = ProcessList.HOME_APP_ADJ;
17244                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17245                 app.cached = false;
17246                 app.adjType = "home";
17247             }
17248             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17249                 procState = ActivityManager.PROCESS_STATE_HOME;
17250             }
17251         }
17252
17253         if (app == mPreviousProcess && app.activities.size() > 0) {
17254             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17255                 // This was the previous process that showed UI to the user.
17256                 // We want to try to keep it around more aggressively, to give
17257                 // a good experience around switching between two apps.
17258                 adj = ProcessList.PREVIOUS_APP_ADJ;
17259                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17260                 app.cached = false;
17261                 app.adjType = "previous";
17262             }
17263             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17264                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17265             }
17266         }
17267
17268         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17269                 + " reason=" + app.adjType);
17270
17271         // By default, we use the computed adjustment.  It may be changed if
17272         // there are applications dependent on our services or providers, but
17273         // this gives us a baseline and makes sure we don't get into an
17274         // infinite recursion.
17275         app.adjSeq = mAdjSeq;
17276         app.curRawAdj = adj;
17277         app.hasStartedServices = false;
17278
17279         if (mBackupTarget != null && app == mBackupTarget.app) {
17280             // If possible we want to avoid killing apps while they're being backed up
17281             if (adj > ProcessList.BACKUP_APP_ADJ) {
17282                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17283                 adj = ProcessList.BACKUP_APP_ADJ;
17284                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17285                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17286                 }
17287                 app.adjType = "backup";
17288                 app.cached = false;
17289             }
17290             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17291                 procState = ActivityManager.PROCESS_STATE_BACKUP;
17292             }
17293         }
17294
17295         boolean mayBeTop = false;
17296
17297         for (int is = app.services.size()-1;
17298                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17299                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17300                         || procState > ActivityManager.PROCESS_STATE_TOP);
17301                 is--) {
17302             ServiceRecord s = app.services.valueAt(is);
17303             if (s.startRequested) {
17304                 app.hasStartedServices = true;
17305                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17306                     procState = ActivityManager.PROCESS_STATE_SERVICE;
17307                 }
17308                 if (app.hasShownUi && app != mHomeProcess) {
17309                     // If this process has shown some UI, let it immediately
17310                     // go to the LRU list because it may be pretty heavy with
17311                     // UI stuff.  We'll tag it with a label just to help
17312                     // debug and understand what is going on.
17313                     if (adj > ProcessList.SERVICE_ADJ) {
17314                         app.adjType = "cch-started-ui-services";
17315                     }
17316                 } else {
17317                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17318                         // This service has seen some activity within
17319                         // recent memory, so we will keep its process ahead
17320                         // of the background processes.
17321                         if (adj > ProcessList.SERVICE_ADJ) {
17322                             adj = ProcessList.SERVICE_ADJ;
17323                             app.adjType = "started-services";
17324                             app.cached = false;
17325                         }
17326                     }
17327                     // If we have let the service slide into the background
17328                     // state, still have some text describing what it is doing
17329                     // even though the service no longer has an impact.
17330                     if (adj > ProcessList.SERVICE_ADJ) {
17331                         app.adjType = "cch-started-services";
17332                     }
17333                 }
17334             }
17335             for (int conni = s.connections.size()-1;
17336                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17337                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17338                             || procState > ActivityManager.PROCESS_STATE_TOP);
17339                     conni--) {
17340                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17341                 for (int i = 0;
17342                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17343                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17344                                 || procState > ActivityManager.PROCESS_STATE_TOP);
17345                         i++) {
17346                     // XXX should compute this based on the max of
17347                     // all connected clients.
17348                     ConnectionRecord cr = clist.get(i);
17349                     if (cr.binding.client == app) {
17350                         // Binding to ourself is not interesting.
17351                         continue;
17352                     }
17353                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17354                         ProcessRecord client = cr.binding.client;
17355                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
17356                                 TOP_APP, doingAll, now);
17357                         int clientProcState = client.curProcState;
17358                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17359                             // If the other app is cached for any reason, for purposes here
17360                             // we are going to consider it empty.  The specific cached state
17361                             // doesn't propagate except under certain conditions.
17362                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17363                         }
17364                         String adjType = null;
17365                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17366                             // Not doing bind OOM management, so treat
17367                             // this guy more like a started service.
17368                             if (app.hasShownUi && app != mHomeProcess) {
17369                                 // If this process has shown some UI, let it immediately
17370                                 // go to the LRU list because it may be pretty heavy with
17371                                 // UI stuff.  We'll tag it with a label just to help
17372                                 // debug and understand what is going on.
17373                                 if (adj > clientAdj) {
17374                                     adjType = "cch-bound-ui-services";
17375                                 }
17376                                 app.cached = false;
17377                                 clientAdj = adj;
17378                                 clientProcState = procState;
17379                             } else {
17380                                 if (now >= (s.lastActivity
17381                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17382                                     // This service has not seen activity within
17383                                     // recent memory, so allow it to drop to the
17384                                     // LRU list if there is no other reason to keep
17385                                     // it around.  We'll also tag it with a label just
17386                                     // to help debug and undertand what is going on.
17387                                     if (adj > clientAdj) {
17388                                         adjType = "cch-bound-services";
17389                                     }
17390                                     clientAdj = adj;
17391                                 }
17392                             }
17393                         }
17394                         if (adj > clientAdj) {
17395                             // If this process has recently shown UI, and
17396                             // the process that is binding to it is less
17397                             // important than being visible, then we don't
17398                             // care about the binding as much as we care
17399                             // about letting this process get into the LRU
17400                             // list to be killed and restarted if needed for
17401                             // memory.
17402                             if (app.hasShownUi && app != mHomeProcess
17403                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17404                                 adjType = "cch-bound-ui-services";
17405                             } else {
17406                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17407                                         |Context.BIND_IMPORTANT)) != 0) {
17408                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17409                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17410                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17411                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17412                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17413                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17414                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17415                                     adj = clientAdj;
17416                                 } else {
17417                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17418                                         adj = ProcessList.VISIBLE_APP_ADJ;
17419                                     }
17420                                 }
17421                                 if (!client.cached) {
17422                                     app.cached = false;
17423                                 }
17424                                 adjType = "service";
17425                             }
17426                         }
17427                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17428                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17429                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17430                             }
17431                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17432                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17433                                     // Special handling of clients who are in the top state.
17434                                     // We *may* want to consider this process to be in the
17435                                     // top state as well, but only if there is not another
17436                                     // reason for it to be running.  Being on the top is a
17437                                     // special state, meaning you are specifically running
17438                                     // for the current top app.  If the process is already
17439                                     // running in the background for some other reason, it
17440                                     // is more important to continue considering it to be
17441                                     // in the background state.
17442                                     mayBeTop = true;
17443                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17444                                 } else {
17445                                     // Special handling for above-top states (persistent
17446                                     // processes).  These should not bring the current process
17447                                     // into the top state, since they are not on top.  Instead
17448                                     // give them the best state after that.
17449                                     clientProcState =
17450                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17451                                 }
17452                             }
17453                         } else {
17454                             if (clientProcState <
17455                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17456                                 clientProcState =
17457                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17458                             }
17459                         }
17460                         if (procState > clientProcState) {
17461                             procState = clientProcState;
17462                         }
17463                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17464                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17465                             app.pendingUiClean = true;
17466                         }
17467                         if (adjType != null) {
17468                             app.adjType = adjType;
17469                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17470                                     .REASON_SERVICE_IN_USE;
17471                             app.adjSource = cr.binding.client;
17472                             app.adjSourceProcState = clientProcState;
17473                             app.adjTarget = s.name;
17474                         }
17475                     }
17476                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17477                         app.treatLikeActivity = true;
17478                     }
17479                     final ActivityRecord a = cr.activity;
17480                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17481                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17482                                 (a.visible || a.state == ActivityState.RESUMED
17483                                  || a.state == ActivityState.PAUSING)) {
17484                             adj = ProcessList.FOREGROUND_APP_ADJ;
17485                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17486                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17487                             }
17488                             app.cached = false;
17489                             app.adjType = "service";
17490                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17491                                     .REASON_SERVICE_IN_USE;
17492                             app.adjSource = a;
17493                             app.adjSourceProcState = procState;
17494                             app.adjTarget = s.name;
17495                         }
17496                     }
17497                 }
17498             }
17499         }
17500
17501         for (int provi = app.pubProviders.size()-1;
17502                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17503                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17504                         || procState > ActivityManager.PROCESS_STATE_TOP);
17505                 provi--) {
17506             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17507             for (int i = cpr.connections.size()-1;
17508                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17509                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17510                             || procState > ActivityManager.PROCESS_STATE_TOP);
17511                     i--) {
17512                 ContentProviderConnection conn = cpr.connections.get(i);
17513                 ProcessRecord client = conn.client;
17514                 if (client == app) {
17515                     // Being our own client is not interesting.
17516                     continue;
17517                 }
17518                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17519                 int clientProcState = client.curProcState;
17520                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17521                     // If the other app is cached for any reason, for purposes here
17522                     // we are going to consider it empty.
17523                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17524                 }
17525                 if (adj > clientAdj) {
17526                     if (app.hasShownUi && app != mHomeProcess
17527                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17528                         app.adjType = "cch-ui-provider";
17529                     } else {
17530                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17531                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17532                         app.adjType = "provider";
17533                     }
17534                     app.cached &= client.cached;
17535                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17536                             .REASON_PROVIDER_IN_USE;
17537                     app.adjSource = client;
17538                     app.adjSourceProcState = clientProcState;
17539                     app.adjTarget = cpr.name;
17540                 }
17541                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17542                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17543                         // Special handling of clients who are in the top state.
17544                         // We *may* want to consider this process to be in the
17545                         // top state as well, but only if there is not another
17546                         // reason for it to be running.  Being on the top is a
17547                         // special state, meaning you are specifically running
17548                         // for the current top app.  If the process is already
17549                         // running in the background for some other reason, it
17550                         // is more important to continue considering it to be
17551                         // in the background state.
17552                         mayBeTop = true;
17553                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17554                     } else {
17555                         // Special handling for above-top states (persistent
17556                         // processes).  These should not bring the current process
17557                         // into the top state, since they are not on top.  Instead
17558                         // give them the best state after that.
17559                         clientProcState =
17560                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17561                     }
17562                 }
17563                 if (procState > clientProcState) {
17564                     procState = clientProcState;
17565                 }
17566                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17567                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17568                 }
17569             }
17570             // If the provider has external (non-framework) process
17571             // dependencies, ensure that its adjustment is at least
17572             // FOREGROUND_APP_ADJ.
17573             if (cpr.hasExternalProcessHandles()) {
17574                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17575                     adj = ProcessList.FOREGROUND_APP_ADJ;
17576                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17577                     app.cached = false;
17578                     app.adjType = "provider";
17579                     app.adjTarget = cpr.name;
17580                 }
17581                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17582                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17583                 }
17584             }
17585         }
17586
17587         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17588             // A client of one of our services or providers is in the top state.  We
17589             // *may* want to be in the top state, but not if we are already running in
17590             // the background for some other reason.  For the decision here, we are going
17591             // to pick out a few specific states that we want to remain in when a client
17592             // is top (states that tend to be longer-term) and otherwise allow it to go
17593             // to the top state.
17594             switch (procState) {
17595                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17596                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17597                 case ActivityManager.PROCESS_STATE_SERVICE:
17598                     // These all are longer-term states, so pull them up to the top
17599                     // of the background states, but not all the way to the top state.
17600                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17601                     break;
17602                 default:
17603                     // Otherwise, top is a better choice, so take it.
17604                     procState = ActivityManager.PROCESS_STATE_TOP;
17605                     break;
17606             }
17607         }
17608
17609         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17610             if (app.hasClientActivities) {
17611                 // This is a cached process, but with client activities.  Mark it so.
17612                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17613                 app.adjType = "cch-client-act";
17614             } else if (app.treatLikeActivity) {
17615                 // This is a cached process, but somebody wants us to treat it like it has
17616                 // an activity, okay!
17617                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17618                 app.adjType = "cch-as-act";
17619             }
17620         }
17621
17622         if (adj == ProcessList.SERVICE_ADJ) {
17623             if (doingAll) {
17624                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17625                 mNewNumServiceProcs++;
17626                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17627                 if (!app.serviceb) {
17628                     // This service isn't far enough down on the LRU list to
17629                     // normally be a B service, but if we are low on RAM and it
17630                     // is large we want to force it down since we would prefer to
17631                     // keep launcher over it.
17632                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17633                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17634                         app.serviceHighRam = true;
17635                         app.serviceb = true;
17636                         //Slog.i(TAG, "ADJ " + app + " high ram!");
17637                     } else {
17638                         mNewNumAServiceProcs++;
17639                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
17640                     }
17641                 } else {
17642                     app.serviceHighRam = false;
17643                 }
17644             }
17645             if (app.serviceb) {
17646                 adj = ProcessList.SERVICE_B_ADJ;
17647             }
17648         }
17649
17650         app.curRawAdj = adj;
17651         
17652         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17653         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17654         if (adj > app.maxAdj) {
17655             adj = app.maxAdj;
17656             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17657                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17658             }
17659         }
17660
17661         // Do final modification to adj.  Everything we do between here and applying
17662         // the final setAdj must be done in this function, because we will also use
17663         // it when computing the final cached adj later.  Note that we don't need to
17664         // worry about this for max adj above, since max adj will always be used to
17665         // keep it out of the cached vaues.
17666         app.curAdj = app.modifyRawOomAdj(adj);
17667         app.curSchedGroup = schedGroup;
17668         app.curProcState = procState;
17669         app.foregroundActivities = foregroundActivities;
17670
17671         return app.curRawAdj;
17672     }
17673
17674     /**
17675      * Record new PSS sample for a process.
17676      */
17677     void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17678         proc.lastPssTime = now;
17679         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17680         if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17681                 + ": " + pss + " lastPss=" + proc.lastPss
17682                 + " state=" + ProcessList.makeProcStateString(procState));
17683         if (proc.initialIdlePss == 0) {
17684             proc.initialIdlePss = pss;
17685         }
17686         proc.lastPss = pss;
17687         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17688             proc.lastCachedPss = pss;
17689         }
17690     }
17691
17692     /**
17693      * Schedule PSS collection of a process.
17694      */
17695     void requestPssLocked(ProcessRecord proc, int procState) {
17696         if (mPendingPssProcesses.contains(proc)) {
17697             return;
17698         }
17699         if (mPendingPssProcesses.size() == 0) {
17700             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17701         }
17702         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17703         proc.pssProcState = procState;
17704         mPendingPssProcesses.add(proc);
17705     }
17706
17707     /**
17708      * Schedule PSS collection of all processes.
17709      */
17710     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17711         if (!always) {
17712             if (now < (mLastFullPssTime +
17713                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17714                 return;
17715             }
17716         }
17717         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17718         mLastFullPssTime = now;
17719         mFullPssPending = true;
17720         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17721         mPendingPssProcesses.clear();
17722         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17723             ProcessRecord app = mLruProcesses.get(i);
17724             if (app.thread == null
17725                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17726                 continue;
17727             }
17728             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17729                 app.pssProcState = app.setProcState;
17730                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17731                         mTestPssMode, isSleeping(), now);
17732                 mPendingPssProcesses.add(app);
17733             }
17734         }
17735         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17736     }
17737
17738     public void setTestPssMode(boolean enabled) {
17739         synchronized (this) {
17740             mTestPssMode = enabled;
17741             if (enabled) {
17742                 // Whenever we enable the mode, we want to take a snapshot all of current
17743                 // process mem use.
17744                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17745             }
17746         }
17747     }
17748
17749     /**
17750      * Ask a given process to GC right now.
17751      */
17752     final void performAppGcLocked(ProcessRecord app) {
17753         try {
17754             app.lastRequestedGc = SystemClock.uptimeMillis();
17755             if (app.thread != null) {
17756                 if (app.reportLowMemory) {
17757                     app.reportLowMemory = false;
17758                     app.thread.scheduleLowMemory();
17759                 } else {
17760                     app.thread.processInBackground();
17761                 }
17762             }
17763         } catch (Exception e) {
17764             // whatever.
17765         }
17766     }
17767     
17768     /**
17769      * Returns true if things are idle enough to perform GCs.
17770      */
17771     private final boolean canGcNowLocked() {
17772         boolean processingBroadcasts = false;
17773         for (BroadcastQueue q : mBroadcastQueues) {
17774             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17775                 processingBroadcasts = true;
17776             }
17777         }
17778         return !processingBroadcasts
17779                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17780     }
17781     
17782     /**
17783      * Perform GCs on all processes that are waiting for it, but only
17784      * if things are idle.
17785      */
17786     final void performAppGcsLocked() {
17787         final int N = mProcessesToGc.size();
17788         if (N <= 0) {
17789             return;
17790         }
17791         if (canGcNowLocked()) {
17792             while (mProcessesToGc.size() > 0) {
17793                 ProcessRecord proc = mProcessesToGc.remove(0);
17794                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17795                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17796                             <= SystemClock.uptimeMillis()) {
17797                         // To avoid spamming the system, we will GC processes one
17798                         // at a time, waiting a few seconds between each.
17799                         performAppGcLocked(proc);
17800                         scheduleAppGcsLocked();
17801                         return;
17802                     } else {
17803                         // It hasn't been long enough since we last GCed this
17804                         // process...  put it in the list to wait for its time.
17805                         addProcessToGcListLocked(proc);
17806                         break;
17807                     }
17808                 }
17809             }
17810             
17811             scheduleAppGcsLocked();
17812         }
17813     }
17814     
17815     /**
17816      * If all looks good, perform GCs on all processes waiting for them.
17817      */
17818     final void performAppGcsIfAppropriateLocked() {
17819         if (canGcNowLocked()) {
17820             performAppGcsLocked();
17821             return;
17822         }
17823         // Still not idle, wait some more.
17824         scheduleAppGcsLocked();
17825     }
17826
17827     /**
17828      * Schedule the execution of all pending app GCs.
17829      */
17830     final void scheduleAppGcsLocked() {
17831         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17832         
17833         if (mProcessesToGc.size() > 0) {
17834             // Schedule a GC for the time to the next process.
17835             ProcessRecord proc = mProcessesToGc.get(0);
17836             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17837             
17838             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17839             long now = SystemClock.uptimeMillis();
17840             if (when < (now+GC_TIMEOUT)) {
17841                 when = now + GC_TIMEOUT;
17842             }
17843             mHandler.sendMessageAtTime(msg, when);
17844         }
17845     }
17846     
17847     /**
17848      * Add a process to the array of processes waiting to be GCed.  Keeps the
17849      * list in sorted order by the last GC time.  The process can't already be
17850      * on the list.
17851      */
17852     final void addProcessToGcListLocked(ProcessRecord proc) {
17853         boolean added = false;
17854         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17855             if (mProcessesToGc.get(i).lastRequestedGc <
17856                     proc.lastRequestedGc) {
17857                 added = true;
17858                 mProcessesToGc.add(i+1, proc);
17859                 break;
17860             }
17861         }
17862         if (!added) {
17863             mProcessesToGc.add(0, proc);
17864         }
17865     }
17866     
17867     /**
17868      * Set up to ask a process to GC itself.  This will either do it
17869      * immediately, or put it on the list of processes to gc the next
17870      * time things are idle.
17871      */
17872     final void scheduleAppGcLocked(ProcessRecord app) {
17873         long now = SystemClock.uptimeMillis();
17874         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17875             return;
17876         }
17877         if (!mProcessesToGc.contains(app)) {
17878             addProcessToGcListLocked(app);
17879             scheduleAppGcsLocked();
17880         }
17881     }
17882
17883     final void checkExcessivePowerUsageLocked(boolean doKills) {
17884         updateCpuStatsNow();
17885
17886         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17887         boolean doWakeKills = doKills;
17888         boolean doCpuKills = doKills;
17889         if (mLastPowerCheckRealtime == 0) {
17890             doWakeKills = false;
17891         }
17892         if (mLastPowerCheckUptime == 0) {
17893             doCpuKills = false;
17894         }
17895         if (stats.isScreenOn()) {
17896             doWakeKills = false;
17897         }
17898         final long curRealtime = SystemClock.elapsedRealtime();
17899         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17900         final long curUptime = SystemClock.uptimeMillis();
17901         final long uptimeSince = curUptime - mLastPowerCheckUptime;
17902         mLastPowerCheckRealtime = curRealtime;
17903         mLastPowerCheckUptime = curUptime;
17904         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17905             doWakeKills = false;
17906         }
17907         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17908             doCpuKills = false;
17909         }
17910         int i = mLruProcesses.size();
17911         while (i > 0) {
17912             i--;
17913             ProcessRecord app = mLruProcesses.get(i);
17914             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17915                 long wtime;
17916                 synchronized (stats) {
17917                     wtime = stats.getProcessWakeTime(app.info.uid,
17918                             app.pid, curRealtime);
17919                 }
17920                 long wtimeUsed = wtime - app.lastWakeTime;
17921                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17922                 if (DEBUG_POWER) {
17923                     StringBuilder sb = new StringBuilder(128);
17924                     sb.append("Wake for ");
17925                     app.toShortString(sb);
17926                     sb.append(": over ");
17927                     TimeUtils.formatDuration(realtimeSince, sb);
17928                     sb.append(" used ");
17929                     TimeUtils.formatDuration(wtimeUsed, sb);
17930                     sb.append(" (");
17931                     sb.append((wtimeUsed*100)/realtimeSince);
17932                     sb.append("%)");
17933                     Slog.i(TAG, sb.toString());
17934                     sb.setLength(0);
17935                     sb.append("CPU for ");
17936                     app.toShortString(sb);
17937                     sb.append(": over ");
17938                     TimeUtils.formatDuration(uptimeSince, sb);
17939                     sb.append(" used ");
17940                     TimeUtils.formatDuration(cputimeUsed, sb);
17941                     sb.append(" (");
17942                     sb.append((cputimeUsed*100)/uptimeSince);
17943                     sb.append("%)");
17944                     Slog.i(TAG, sb.toString());
17945                 }
17946                 // If a process has held a wake lock for more
17947                 // than 50% of the time during this period,
17948                 // that sounds bad.  Kill!
17949                 if (doWakeKills && realtimeSince > 0
17950                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
17951                     synchronized (stats) {
17952                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17953                                 realtimeSince, wtimeUsed);
17954                     }
17955                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17956                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17957                 } else if (doCpuKills && uptimeSince > 0
17958                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
17959                     synchronized (stats) {
17960                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17961                                 uptimeSince, cputimeUsed);
17962                     }
17963                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17964                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17965                 } else {
17966                     app.lastWakeTime = wtime;
17967                     app.lastCpuTime = app.curCpuTime;
17968                 }
17969             }
17970         }
17971     }
17972
17973     private final boolean applyOomAdjLocked(ProcessRecord app,
17974             ProcessRecord TOP_APP, boolean doingAll, long now) {
17975         boolean success = true;
17976
17977         if (app.curRawAdj != app.setRawAdj) {
17978             app.setRawAdj = app.curRawAdj;
17979         }
17980
17981         int changes = 0;
17982
17983         if (app.curAdj != app.setAdj) {
17984             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17985             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17986                 TAG, "Set " + app.pid + " " + app.processName +
17987                 " adj " + app.curAdj + ": " + app.adjType);
17988             app.setAdj = app.curAdj;
17989         }
17990
17991         if (app.setSchedGroup != app.curSchedGroup) {
17992             app.setSchedGroup = app.curSchedGroup;
17993             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17994                     "Setting process group of " + app.processName
17995                     + " to " + app.curSchedGroup);
17996             if (app.waitingToKill != null &&
17997                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17998                 app.kill(app.waitingToKill, true);
17999                 success = false;
18000             } else {
18001                 if (true) {
18002                     long oldId = Binder.clearCallingIdentity();
18003                     try {
18004                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18005                     } catch (Exception e) {
18006                         Slog.w(TAG, "Failed setting process group of " + app.pid
18007                                 + " to " + app.curSchedGroup);
18008                         e.printStackTrace();
18009                     } finally {
18010                         Binder.restoreCallingIdentity(oldId);
18011                     }
18012                 } else {
18013                     if (app.thread != null) {
18014                         try {
18015                             app.thread.setSchedulingGroup(app.curSchedGroup);
18016                         } catch (RemoteException e) {
18017                         }
18018                     }
18019                 }
18020                 Process.setSwappiness(app.pid,
18021                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18022             }
18023         }
18024         if (app.repForegroundActivities != app.foregroundActivities) {
18025             app.repForegroundActivities = app.foregroundActivities;
18026             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18027         }
18028         if (app.repProcState != app.curProcState) {
18029             app.repProcState = app.curProcState;
18030             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18031             if (app.thread != null) {
18032                 try {
18033                     if (false) {
18034                         //RuntimeException h = new RuntimeException("here");
18035                         Slog.i(TAG, "Sending new process state " + app.repProcState
18036                                 + " to " + app /*, h*/);
18037                     }
18038                     app.thread.setProcessState(app.repProcState);
18039                 } catch (RemoteException e) {
18040                 }
18041             }
18042         }
18043         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18044                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18045             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18046                 // Experimental code to more aggressively collect pss while
18047                 // running test...  the problem is that this tends to collect
18048                 // the data right when a process is transitioning between process
18049                 // states, which well tend to give noisy data.
18050                 long start = SystemClock.uptimeMillis();
18051                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18052                 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
18053                 mPendingPssProcesses.remove(app);
18054                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18055                         + " to " + app.curProcState + ": "
18056                         + (SystemClock.uptimeMillis()-start) + "ms");
18057             }
18058             app.lastStateTime = now;
18059             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18060                     mTestPssMode, isSleeping(), now);
18061             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
18062                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18063                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18064                     + (app.nextPssTime-now) + ": " + app);
18065         } else {
18066             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18067                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18068                     mTestPssMode)))) {
18069                 requestPssLocked(app, app.setProcState);
18070                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18071                         mTestPssMode, isSleeping(), now);
18072             } else if (false && DEBUG_PSS) {
18073                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18074             }
18075         }
18076         if (app.setProcState != app.curProcState) {
18077             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18078                     "Proc state change of " + app.processName
18079                     + " to " + app.curProcState);
18080             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18081             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18082             if (setImportant && !curImportant) {
18083                 // This app is no longer something we consider important enough to allow to
18084                 // use arbitrary amounts of battery power.  Note
18085                 // its current wake lock time to later know to kill it if
18086                 // it is not behaving well.
18087                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18088                 synchronized (stats) {
18089                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18090                             app.pid, SystemClock.elapsedRealtime());
18091                 }
18092                 app.lastCpuTime = app.curCpuTime;
18093
18094             }
18095             app.setProcState = app.curProcState;
18096             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18097                 app.notCachedSinceIdle = false;
18098             }
18099             if (!doingAll) {
18100                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18101             } else {
18102                 app.procStateChanged = true;
18103             }
18104         }
18105
18106         if (changes != 0) {
18107             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18108             int i = mPendingProcessChanges.size()-1;
18109             ProcessChangeItem item = null;
18110             while (i >= 0) {
18111                 item = mPendingProcessChanges.get(i);
18112                 if (item.pid == app.pid) {
18113                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18114                     break;
18115                 }
18116                 i--;
18117             }
18118             if (i < 0) {
18119                 // No existing item in pending changes; need a new one.
18120                 final int NA = mAvailProcessChanges.size();
18121                 if (NA > 0) {
18122                     item = mAvailProcessChanges.remove(NA-1);
18123                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18124                 } else {
18125                     item = new ProcessChangeItem();
18126                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18127                 }
18128                 item.changes = 0;
18129                 item.pid = app.pid;
18130                 item.uid = app.info.uid;
18131                 if (mPendingProcessChanges.size() == 0) {
18132                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18133                             "*** Enqueueing dispatch processes changed!");
18134                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18135                 }
18136                 mPendingProcessChanges.add(item);
18137             }
18138             item.changes |= changes;
18139             item.processState = app.repProcState;
18140             item.foregroundActivities = app.repForegroundActivities;
18141             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18142                     + Integer.toHexString(System.identityHashCode(item))
18143                     + " " + app.toShortString() + ": changes=" + item.changes
18144                     + " procState=" + item.processState
18145                     + " foreground=" + item.foregroundActivities
18146                     + " type=" + app.adjType + " source=" + app.adjSource
18147                     + " target=" + app.adjTarget);
18148         }
18149
18150         return success;
18151     }
18152
18153     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18154         if (proc.thread != null) {
18155             if (proc.baseProcessTracker != null) {
18156                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18157             }
18158             if (proc.repProcState >= 0) {
18159                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18160                         proc.repProcState);
18161             }
18162         }
18163     }
18164
18165     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18166             ProcessRecord TOP_APP, boolean doingAll, long now) {
18167         if (app.thread == null) {
18168             return false;
18169         }
18170
18171         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18172
18173         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18174     }
18175
18176     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18177             boolean oomAdj) {
18178         if (isForeground != proc.foregroundServices) {
18179             proc.foregroundServices = isForeground;
18180             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18181                     proc.info.uid);
18182             if (isForeground) {
18183                 if (curProcs == null) {
18184                     curProcs = new ArrayList<ProcessRecord>();
18185                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18186                 }
18187                 if (!curProcs.contains(proc)) {
18188                     curProcs.add(proc);
18189                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18190                             proc.info.packageName, proc.info.uid);
18191                 }
18192             } else {
18193                 if (curProcs != null) {
18194                     if (curProcs.remove(proc)) {
18195                         mBatteryStatsService.noteEvent(
18196                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18197                                 proc.info.packageName, proc.info.uid);
18198                         if (curProcs.size() <= 0) {
18199                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18200                         }
18201                     }
18202                 }
18203             }
18204             if (oomAdj) {
18205                 updateOomAdjLocked();
18206             }
18207         }
18208     }
18209
18210     private final ActivityRecord resumedAppLocked() {
18211         ActivityRecord act = mStackSupervisor.resumedAppLocked();
18212         String pkg;
18213         int uid;
18214         if (act != null) {
18215             pkg = act.packageName;
18216             uid = act.info.applicationInfo.uid;
18217         } else {
18218             pkg = null;
18219             uid = -1;
18220         }
18221         // Has the UID or resumed package name changed?
18222         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18223                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18224             if (mCurResumedPackage != null) {
18225                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18226                         mCurResumedPackage, mCurResumedUid);
18227             }
18228             mCurResumedPackage = pkg;
18229             mCurResumedUid = uid;
18230             if (mCurResumedPackage != null) {
18231                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18232                         mCurResumedPackage, mCurResumedUid);
18233             }
18234         }
18235         return act;
18236     }
18237
18238     final boolean updateOomAdjLocked(ProcessRecord app) {
18239         final ActivityRecord TOP_ACT = resumedAppLocked();
18240         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18241         final boolean wasCached = app.cached;
18242
18243         mAdjSeq++;
18244
18245         // This is the desired cached adjusment we want to tell it to use.
18246         // If our app is currently cached, we know it, and that is it.  Otherwise,
18247         // we don't know it yet, and it needs to now be cached we will then
18248         // need to do a complete oom adj.
18249         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18250                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18251         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18252                 SystemClock.uptimeMillis());
18253         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18254             // Changed to/from cached state, so apps after it in the LRU
18255             // list may also be changed.
18256             updateOomAdjLocked();
18257         }
18258         return success;
18259     }
18260
18261     final void updateOomAdjLocked() {
18262         final ActivityRecord TOP_ACT = resumedAppLocked();
18263         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18264         final long now = SystemClock.uptimeMillis();
18265         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18266         final int N = mLruProcesses.size();
18267
18268         if (false) {
18269             RuntimeException e = new RuntimeException();
18270             e.fillInStackTrace();
18271             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18272         }
18273
18274         mAdjSeq++;
18275         mNewNumServiceProcs = 0;
18276         mNewNumAServiceProcs = 0;
18277
18278         final int emptyProcessLimit;
18279         final int cachedProcessLimit;
18280         if (mProcessLimit <= 0) {
18281             emptyProcessLimit = cachedProcessLimit = 0;
18282         } else if (mProcessLimit == 1) {
18283             emptyProcessLimit = 1;
18284             cachedProcessLimit = 0;
18285         } else {
18286             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18287             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18288         }
18289
18290         // Let's determine how many processes we have running vs.
18291         // how many slots we have for background processes; we may want
18292         // to put multiple processes in a slot of there are enough of
18293         // them.
18294         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18295                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18296         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18297         if (numEmptyProcs > cachedProcessLimit) {
18298             // If there are more empty processes than our limit on cached
18299             // processes, then use the cached process limit for the factor.
18300             // This ensures that the really old empty processes get pushed
18301             // down to the bottom, so if we are running low on memory we will
18302             // have a better chance at keeping around more cached processes
18303             // instead of a gazillion empty processes.
18304             numEmptyProcs = cachedProcessLimit;
18305         }
18306         int emptyFactor = numEmptyProcs/numSlots;
18307         if (emptyFactor < 1) emptyFactor = 1;
18308         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18309         if (cachedFactor < 1) cachedFactor = 1;
18310         int stepCached = 0;
18311         int stepEmpty = 0;
18312         int numCached = 0;
18313         int numEmpty = 0;
18314         int numTrimming = 0;
18315
18316         mNumNonCachedProcs = 0;
18317         mNumCachedHiddenProcs = 0;
18318
18319         // First update the OOM adjustment for each of the
18320         // application processes based on their current state.
18321         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18322         int nextCachedAdj = curCachedAdj+1;
18323         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18324         int nextEmptyAdj = curEmptyAdj+2;
18325         for (int i=N-1; i>=0; i--) {
18326             ProcessRecord app = mLruProcesses.get(i);
18327             if (!app.killedByAm && app.thread != null) {
18328                 app.procStateChanged = false;
18329                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18330
18331                 // If we haven't yet assigned the final cached adj
18332                 // to the process, do that now.
18333                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18334                     switch (app.curProcState) {
18335                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18336                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18337                             // This process is a cached process holding activities...
18338                             // assign it the next cached value for that type, and then
18339                             // step that cached level.
18340                             app.curRawAdj = curCachedAdj;
18341                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18342                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18343                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18344                                     + ")");
18345                             if (curCachedAdj != nextCachedAdj) {
18346                                 stepCached++;
18347                                 if (stepCached >= cachedFactor) {
18348                                     stepCached = 0;
18349                                     curCachedAdj = nextCachedAdj;
18350                                     nextCachedAdj += 2;
18351                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18352                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18353                                     }
18354                                 }
18355                             }
18356                             break;
18357                         default:
18358                             // For everything else, assign next empty cached process
18359                             // level and bump that up.  Note that this means that
18360                             // long-running services that have dropped down to the
18361                             // cached level will be treated as empty (since their process
18362                             // state is still as a service), which is what we want.
18363                             app.curRawAdj = curEmptyAdj;
18364                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18365                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18366                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18367                                     + ")");
18368                             if (curEmptyAdj != nextEmptyAdj) {
18369                                 stepEmpty++;
18370                                 if (stepEmpty >= emptyFactor) {
18371                                     stepEmpty = 0;
18372                                     curEmptyAdj = nextEmptyAdj;
18373                                     nextEmptyAdj += 2;
18374                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18375                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18376                                     }
18377                                 }
18378                             }
18379                             break;
18380                     }
18381                 }
18382
18383                 applyOomAdjLocked(app, TOP_APP, true, now);
18384
18385                 // Count the number of process types.
18386                 switch (app.curProcState) {
18387                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18388                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18389                         mNumCachedHiddenProcs++;
18390                         numCached++;
18391                         if (numCached > cachedProcessLimit) {
18392                             app.kill("cached #" + numCached, true);
18393                         }
18394                         break;
18395                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18396                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18397                                 && app.lastActivityTime < oldTime) {
18398                             app.kill("empty for "
18399                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18400                                     / 1000) + "s", true);
18401                         } else {
18402                             numEmpty++;
18403                             if (numEmpty > emptyProcessLimit) {
18404                                 app.kill("empty #" + numEmpty, true);
18405                             }
18406                         }
18407                         break;
18408                     default:
18409                         mNumNonCachedProcs++;
18410                         break;
18411                 }
18412
18413                 if (app.isolated && app.services.size() <= 0) {
18414                     // If this is an isolated process, and there are no
18415                     // services running in it, then the process is no longer
18416                     // needed.  We agressively kill these because we can by
18417                     // definition not re-use the same process again, and it is
18418                     // good to avoid having whatever code was running in them
18419                     // left sitting around after no longer needed.
18420                     app.kill("isolated not needed", true);
18421                 }
18422
18423                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18424                         && !app.killedByAm) {
18425                     numTrimming++;
18426                 }
18427             }
18428         }
18429
18430         mNumServiceProcs = mNewNumServiceProcs;
18431
18432         // Now determine the memory trimming level of background processes.
18433         // Unfortunately we need to start at the back of the list to do this
18434         // properly.  We only do this if the number of background apps we
18435         // are managing to keep around is less than half the maximum we desire;
18436         // if we are keeping a good number around, we'll let them use whatever
18437         // memory they want.
18438         final int numCachedAndEmpty = numCached + numEmpty;
18439         int memFactor;
18440         if (numCached <= ProcessList.TRIM_CACHED_APPS
18441                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18442             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18443                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18444             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18445                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18446             } else {
18447                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18448             }
18449         } else {
18450             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18451         }
18452         // We always allow the memory level to go up (better).  We only allow it to go
18453         // down if we are in a state where that is allowed, *and* the total number of processes
18454         // has gone down since last time.
18455         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18456                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18457                 + " last=" + mLastNumProcesses);
18458         if (memFactor > mLastMemoryLevel) {
18459             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18460                 memFactor = mLastMemoryLevel;
18461                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18462             }
18463         }
18464         mLastMemoryLevel = memFactor;
18465         mLastNumProcesses = mLruProcesses.size();
18466         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18467         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18468         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18469             if (mLowRamStartTime == 0) {
18470                 mLowRamStartTime = now;
18471             }
18472             int step = 0;
18473             int fgTrimLevel;
18474             switch (memFactor) {
18475                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18476                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18477                     break;
18478                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
18479                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18480                     break;
18481                 default:
18482                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18483                     break;
18484             }
18485             int factor = numTrimming/3;
18486             int minFactor = 2;
18487             if (mHomeProcess != null) minFactor++;
18488             if (mPreviousProcess != null) minFactor++;
18489             if (factor < minFactor) factor = minFactor;
18490             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18491             for (int i=N-1; i>=0; i--) {
18492                 ProcessRecord app = mLruProcesses.get(i);
18493                 if (allChanged || app.procStateChanged) {
18494                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
18495                     app.procStateChanged = false;
18496                 }
18497                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18498                         && !app.killedByAm) {
18499                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
18500                         try {
18501                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18502                                     "Trimming memory of " + app.processName
18503                                     + " to " + curLevel);
18504                             app.thread.scheduleTrimMemory(curLevel);
18505                         } catch (RemoteException e) {
18506                         }
18507                         if (false) {
18508                             // For now we won't do this; our memory trimming seems
18509                             // to be good enough at this point that destroying
18510                             // activities causes more harm than good.
18511                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18512                                     && app != mHomeProcess && app != mPreviousProcess) {
18513                                 // Need to do this on its own message because the stack may not
18514                                 // be in a consistent state at this point.
18515                                 // For these apps we will also finish their activities
18516                                 // to help them free memory.
18517                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18518                             }
18519                         }
18520                     }
18521                     app.trimMemoryLevel = curLevel;
18522                     step++;
18523                     if (step >= factor) {
18524                         step = 0;
18525                         switch (curLevel) {
18526                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18527                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18528                                 break;
18529                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18530                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18531                                 break;
18532                         }
18533                     }
18534                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18535                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18536                             && app.thread != null) {
18537                         try {
18538                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18539                                     "Trimming memory of heavy-weight " + app.processName
18540                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18541                             app.thread.scheduleTrimMemory(
18542                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18543                         } catch (RemoteException e) {
18544                         }
18545                     }
18546                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18547                 } else {
18548                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18549                             || app.systemNoUi) && app.pendingUiClean) {
18550                         // If this application is now in the background and it
18551                         // had done UI, then give it the special trim level to
18552                         // have it free UI resources.
18553                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18554                         if (app.trimMemoryLevel < level && app.thread != null) {
18555                             try {
18556                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18557                                         "Trimming memory of bg-ui " + app.processName
18558                                         + " to " + level);
18559                                 app.thread.scheduleTrimMemory(level);
18560                             } catch (RemoteException e) {
18561                             }
18562                         }
18563                         app.pendingUiClean = false;
18564                     }
18565                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18566                         try {
18567                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18568                                     "Trimming memory of fg " + app.processName
18569                                     + " to " + fgTrimLevel);
18570                             app.thread.scheduleTrimMemory(fgTrimLevel);
18571                         } catch (RemoteException e) {
18572                         }
18573                     }
18574                     app.trimMemoryLevel = fgTrimLevel;
18575                 }
18576             }
18577         } else {
18578             if (mLowRamStartTime != 0) {
18579                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18580                 mLowRamStartTime = 0;
18581             }
18582             for (int i=N-1; i>=0; i--) {
18583                 ProcessRecord app = mLruProcesses.get(i);
18584                 if (allChanged || app.procStateChanged) {
18585                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
18586                     app.procStateChanged = false;
18587                 }
18588                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18589                         || app.systemNoUi) && app.pendingUiClean) {
18590                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18591                             && app.thread != null) {
18592                         try {
18593                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18594                                     "Trimming memory of ui hidden " + app.processName
18595                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18596                             app.thread.scheduleTrimMemory(
18597                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18598                         } catch (RemoteException e) {
18599                         }
18600                     }
18601                     app.pendingUiClean = false;
18602                 }
18603                 app.trimMemoryLevel = 0;
18604             }
18605         }
18606
18607         if (mAlwaysFinishActivities) {
18608             // Need to do this on its own message because the stack may not
18609             // be in a consistent state at this point.
18610             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18611         }
18612
18613         if (allChanged) {
18614             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18615         }
18616
18617         if (mProcessStats.shouldWriteNowLocked(now)) {
18618             mHandler.post(new Runnable() {
18619                 @Override public void run() {
18620                     synchronized (ActivityManagerService.this) {
18621                         mProcessStats.writeStateAsyncLocked();
18622                     }
18623                 }
18624             });
18625         }
18626
18627         if (DEBUG_OOM_ADJ) {
18628             if (false) {
18629                 RuntimeException here = new RuntimeException("here");
18630                 here.fillInStackTrace();
18631                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18632             } else {
18633                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18634             }
18635         }
18636     }
18637
18638     final void trimApplications() {
18639         synchronized (this) {
18640             int i;
18641
18642             // First remove any unused application processes whose package
18643             // has been removed.
18644             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18645                 final ProcessRecord app = mRemovedProcesses.get(i);
18646                 if (app.activities.size() == 0
18647                         && app.curReceiver == null && app.services.size() == 0) {
18648                     Slog.i(
18649                         TAG, "Exiting empty application process "
18650                         + app.processName + " ("
18651                         + (app.thread != null ? app.thread.asBinder() : null)
18652                         + ")\n");
18653                     if (app.pid > 0 && app.pid != MY_PID) {
18654                         app.kill("empty", false);
18655                     } else {
18656                         try {
18657                             app.thread.scheduleExit();
18658                         } catch (Exception e) {
18659                             // Ignore exceptions.
18660                         }
18661                     }
18662                     cleanUpApplicationRecordLocked(app, false, true, -1);
18663                     mRemovedProcesses.remove(i);
18664
18665                     if (app.persistent) {
18666                         addAppLocked(app.info, false, null /* ABI override */);
18667                     }
18668                 }
18669             }
18670
18671             // Now update the oom adj for all processes.
18672             updateOomAdjLocked();
18673         }
18674     }
18675
18676     /** This method sends the specified signal to each of the persistent apps */
18677     public void signalPersistentProcesses(int sig) throws RemoteException {
18678         if (sig != Process.SIGNAL_USR1) {
18679             throw new SecurityException("Only SIGNAL_USR1 is allowed");
18680         }
18681
18682         synchronized (this) {
18683             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18684                     != PackageManager.PERMISSION_GRANTED) {
18685                 throw new SecurityException("Requires permission "
18686                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18687             }
18688
18689             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18690                 ProcessRecord r = mLruProcesses.get(i);
18691                 if (r.thread != null && r.persistent) {
18692                     Process.sendSignal(r.pid, sig);
18693                 }
18694             }
18695         }
18696     }
18697
18698     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18699         if (proc == null || proc == mProfileProc) {
18700             proc = mProfileProc;
18701             profileType = mProfileType;
18702             clearProfilerLocked();
18703         }
18704         if (proc == null) {
18705             return;
18706         }
18707         try {
18708             proc.thread.profilerControl(false, null, profileType);
18709         } catch (RemoteException e) {
18710             throw new IllegalStateException("Process disappeared");
18711         }
18712     }
18713
18714     private void clearProfilerLocked() {
18715         if (mProfileFd != null) {
18716             try {
18717                 mProfileFd.close();
18718             } catch (IOException e) {
18719             }
18720         }
18721         mProfileApp = null;
18722         mProfileProc = null;
18723         mProfileFile = null;
18724         mProfileType = 0;
18725         mAutoStopProfiler = false;
18726         mSamplingInterval = 0;
18727     }
18728
18729     public boolean profileControl(String process, int userId, boolean start,
18730             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18731
18732         try {
18733             synchronized (this) {
18734                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18735                 // its own permission.
18736                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18737                         != PackageManager.PERMISSION_GRANTED) {
18738                     throw new SecurityException("Requires permission "
18739                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18740                 }
18741
18742                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18743                     throw new IllegalArgumentException("null profile info or fd");
18744                 }
18745
18746                 ProcessRecord proc = null;
18747                 if (process != null) {
18748                     proc = findProcessLocked(process, userId, "profileControl");
18749                 }
18750
18751                 if (start && (proc == null || proc.thread == null)) {
18752                     throw new IllegalArgumentException("Unknown process: " + process);
18753                 }
18754
18755                 if (start) {
18756                     stopProfilerLocked(null, 0);
18757                     setProfileApp(proc.info, proc.processName, profilerInfo);
18758                     mProfileProc = proc;
18759                     mProfileType = profileType;
18760                     ParcelFileDescriptor fd = profilerInfo.profileFd;
18761                     try {
18762                         fd = fd.dup();
18763                     } catch (IOException e) {
18764                         fd = null;
18765                     }
18766                     profilerInfo.profileFd = fd;
18767                     proc.thread.profilerControl(start, profilerInfo, profileType);
18768                     fd = null;
18769                     mProfileFd = null;
18770                 } else {
18771                     stopProfilerLocked(proc, profileType);
18772                     if (profilerInfo != null && profilerInfo.profileFd != null) {
18773                         try {
18774                             profilerInfo.profileFd.close();
18775                         } catch (IOException e) {
18776                         }
18777                     }
18778                 }
18779
18780                 return true;
18781             }
18782         } catch (RemoteException e) {
18783             throw new IllegalStateException("Process disappeared");
18784         } finally {
18785             if (profilerInfo != null && profilerInfo.profileFd != null) {
18786                 try {
18787                     profilerInfo.profileFd.close();
18788                 } catch (IOException e) {
18789                 }
18790             }
18791         }
18792     }
18793
18794     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18795         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18796                 userId, true, ALLOW_FULL_ONLY, callName, null);
18797         ProcessRecord proc = null;
18798         try {
18799             int pid = Integer.parseInt(process);
18800             synchronized (mPidsSelfLocked) {
18801                 proc = mPidsSelfLocked.get(pid);
18802             }
18803         } catch (NumberFormatException e) {
18804         }
18805
18806         if (proc == null) {
18807             ArrayMap<String, SparseArray<ProcessRecord>> all
18808                     = mProcessNames.getMap();
18809             SparseArray<ProcessRecord> procs = all.get(process);
18810             if (procs != null && procs.size() > 0) {
18811                 proc = procs.valueAt(0);
18812                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18813                     for (int i=1; i<procs.size(); i++) {
18814                         ProcessRecord thisProc = procs.valueAt(i);
18815                         if (thisProc.userId == userId) {
18816                             proc = thisProc;
18817                             break;
18818                         }
18819                     }
18820                 }
18821             }
18822         }
18823
18824         return proc;
18825     }
18826
18827     public boolean dumpHeap(String process, int userId, boolean managed,
18828             String path, ParcelFileDescriptor fd) throws RemoteException {
18829
18830         try {
18831             synchronized (this) {
18832                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18833                 // its own permission (same as profileControl).
18834                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18835                         != PackageManager.PERMISSION_GRANTED) {
18836                     throw new SecurityException("Requires permission "
18837                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18838                 }
18839
18840                 if (fd == null) {
18841                     throw new IllegalArgumentException("null fd");
18842                 }
18843
18844                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18845                 if (proc == null || proc.thread == null) {
18846                     throw new IllegalArgumentException("Unknown process: " + process);
18847                 }
18848
18849                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18850                 if (!isDebuggable) {
18851                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18852                         throw new SecurityException("Process not debuggable: " + proc);
18853                     }
18854                 }
18855
18856                 proc.thread.dumpHeap(managed, path, fd);
18857                 fd = null;
18858                 return true;
18859             }
18860         } catch (RemoteException e) {
18861             throw new IllegalStateException("Process disappeared");
18862         } finally {
18863             if (fd != null) {
18864                 try {
18865                     fd.close();
18866                 } catch (IOException e) {
18867                 }
18868             }
18869         }
18870     }
18871
18872     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18873     public void monitor() {
18874         synchronized (this) { }
18875     }
18876
18877     void onCoreSettingsChange(Bundle settings) {
18878         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18879             ProcessRecord processRecord = mLruProcesses.get(i);
18880             try {
18881                 if (processRecord.thread != null) {
18882                     processRecord.thread.setCoreSettings(settings);
18883                 }
18884             } catch (RemoteException re) {
18885                 /* ignore */
18886             }
18887         }
18888     }
18889
18890     // Multi-user methods
18891
18892     /**
18893      * Start user, if its not already running, but don't bring it to foreground.
18894      */
18895     @Override
18896     public boolean startUserInBackground(final int userId) {
18897         return startUser(userId, /* foreground */ false);
18898     }
18899
18900     /**
18901      * Start user, if its not already running, and bring it to foreground.
18902      */
18903     boolean startUserInForeground(final int userId, Dialog dlg) {
18904         boolean result = startUser(userId, /* foreground */ true);
18905         dlg.dismiss();
18906         return result;
18907     }
18908
18909     /**
18910      * Refreshes the list of users related to the current user when either a
18911      * user switch happens or when a new related user is started in the
18912      * background.
18913      */
18914     private void updateCurrentProfileIdsLocked() {
18915         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18916                 mCurrentUserId, false /* enabledOnly */);
18917         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18918         for (int i = 0; i < currentProfileIds.length; i++) {
18919             currentProfileIds[i] = profiles.get(i).id;
18920         }
18921         mCurrentProfileIds = currentProfileIds;
18922
18923         synchronized (mUserProfileGroupIdsSelfLocked) {
18924             mUserProfileGroupIdsSelfLocked.clear();
18925             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18926             for (int i = 0; i < users.size(); i++) {
18927                 UserInfo user = users.get(i);
18928                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18929                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18930                 }
18931             }
18932         }
18933     }
18934
18935     private Set getProfileIdsLocked(int userId) {
18936         Set userIds = new HashSet<Integer>();
18937         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18938                 userId, false /* enabledOnly */);
18939         for (UserInfo user : profiles) {
18940             userIds.add(Integer.valueOf(user.id));
18941         }
18942         return userIds;
18943     }
18944
18945     @Override
18946     public boolean switchUser(final int userId) {
18947         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18948         String userName;
18949         synchronized (this) {
18950             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18951             if (userInfo == null) {
18952                 Slog.w(TAG, "No user info for user #" + userId);
18953                 return false;
18954             }
18955             if (userInfo.isManagedProfile()) {
18956                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18957                 return false;
18958             }
18959             userName = userInfo.name;
18960             mTargetUserId = userId;
18961         }
18962         mUiHandler.removeMessages(START_USER_SWITCH_MSG);
18963         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18964         return true;
18965     }
18966
18967     private void showUserSwitchDialog(int userId, String userName) {
18968         // The dialog will show and then initiate the user switch by calling startUserInForeground
18969         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18970                 true /* above system */);
18971         d.show();
18972     }
18973
18974     private boolean startUser(final int userId, final boolean foreground) {
18975         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18976                 != PackageManager.PERMISSION_GRANTED) {
18977             String msg = "Permission Denial: switchUser() from pid="
18978                     + Binder.getCallingPid()
18979                     + ", uid=" + Binder.getCallingUid()
18980                     + " requires " + INTERACT_ACROSS_USERS_FULL;
18981             Slog.w(TAG, msg);
18982             throw new SecurityException(msg);
18983         }
18984
18985         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18986
18987         final long ident = Binder.clearCallingIdentity();
18988         try {
18989             synchronized (this) {
18990                 final int oldUserId = mCurrentUserId;
18991                 if (oldUserId == userId) {
18992                     return true;
18993                 }
18994
18995                 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18996
18997                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18998                 if (userInfo == null) {
18999                     Slog.w(TAG, "No user info for user #" + userId);
19000                     return false;
19001                 }
19002                 if (foreground && userInfo.isManagedProfile()) {
19003                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19004                     return false;
19005                 }
19006
19007                 if (foreground) {
19008                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19009                             R.anim.screen_user_enter);
19010                 }
19011
19012                 boolean needStart = false;
19013
19014                 // If the user we are switching to is not currently started, then
19015                 // we need to start it now.
19016                 if (mStartedUsers.get(userId) == null) {
19017                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19018                     updateStartedUserArrayLocked();
19019                     needStart = true;
19020                 }
19021
19022                 final Integer userIdInt = Integer.valueOf(userId);
19023                 mUserLru.remove(userIdInt);
19024                 mUserLru.add(userIdInt);
19025
19026                 if (foreground) {
19027                     mCurrentUserId = userId;
19028                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19029                     updateCurrentProfileIdsLocked();
19030                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19031                     // Once the internal notion of the active user has switched, we lock the device
19032                     // with the option to show the user switcher on the keyguard.
19033                     mWindowManager.lockNow(null);
19034                 } else {
19035                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19036                     updateCurrentProfileIdsLocked();
19037                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19038                     mUserLru.remove(currentUserIdInt);
19039                     mUserLru.add(currentUserIdInt);
19040                 }
19041
19042                 final UserStartedState uss = mStartedUsers.get(userId);
19043
19044                 // Make sure user is in the started state.  If it is currently
19045                 // stopping, we need to knock that off.
19046                 if (uss.mState == UserStartedState.STATE_STOPPING) {
19047                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19048                     // so we can just fairly silently bring the user back from
19049                     // the almost-dead.
19050                     uss.mState = UserStartedState.STATE_RUNNING;
19051                     updateStartedUserArrayLocked();
19052                     needStart = true;
19053                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19054                     // This means ACTION_SHUTDOWN has been sent, so we will
19055                     // need to treat this as a new boot of the user.
19056                     uss.mState = UserStartedState.STATE_BOOTING;
19057                     updateStartedUserArrayLocked();
19058                     needStart = true;
19059                 }
19060
19061                 if (uss.mState == UserStartedState.STATE_BOOTING) {
19062                     // Booting up a new user, need to tell system services about it.
19063                     // Note that this is on the same handler as scheduling of broadcasts,
19064                     // which is important because it needs to go first.
19065                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19066                 }
19067
19068                 if (foreground) {
19069                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19070                             oldUserId));
19071                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19072                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19073                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19074                             oldUserId, userId, uss));
19075                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19076                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19077                 }
19078
19079                 if (needStart) {
19080                     // Send USER_STARTED broadcast
19081                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19082                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19083                             | Intent.FLAG_RECEIVER_FOREGROUND);
19084                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19085                     broadcastIntentLocked(null, null, intent,
19086                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19087                             false, false, MY_PID, Process.SYSTEM_UID, userId);
19088                 }
19089
19090                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19091                     if (userId != UserHandle.USER_OWNER) {
19092                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19093                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19094                         broadcastIntentLocked(null, null, intent, null,
19095                                 new IIntentReceiver.Stub() {
19096                                     public void performReceive(Intent intent, int resultCode,
19097                                             String data, Bundle extras, boolean ordered,
19098                                             boolean sticky, int sendingUser) {
19099                                         onUserInitialized(uss, foreground, oldUserId, userId);
19100                                     }
19101                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
19102                                 true, false, MY_PID, Process.SYSTEM_UID,
19103                                 userId);
19104                         uss.initializing = true;
19105                     } else {
19106                         getUserManagerLocked().makeInitialized(userInfo.id);
19107                     }
19108                 }
19109
19110                 if (foreground) {
19111                     if (!uss.initializing) {
19112                         moveUserToForeground(uss, oldUserId, userId);
19113                     }
19114                 } else {
19115                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
19116                 }
19117
19118                 if (needStart) {
19119                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19120                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19121                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19122                     broadcastIntentLocked(null, null, intent,
19123                             null, new IIntentReceiver.Stub() {
19124                                 @Override
19125                                 public void performReceive(Intent intent, int resultCode, String data,
19126                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19127                                         throws RemoteException {
19128                                 }
19129                             }, 0, null, null,
19130                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19131                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19132                 }
19133             }
19134         } finally {
19135             Binder.restoreCallingIdentity(ident);
19136         }
19137
19138         return true;
19139     }
19140
19141     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19142         long ident = Binder.clearCallingIdentity();
19143         try {
19144             Intent intent;
19145             if (oldUserId >= 0) {
19146                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19147                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19148                 int count = profiles.size();
19149                 for (int i = 0; i < count; i++) {
19150                     int profileUserId = profiles.get(i).id;
19151                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19152                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19153                             | Intent.FLAG_RECEIVER_FOREGROUND);
19154                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19155                     broadcastIntentLocked(null, null, intent,
19156                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19157                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19158                 }
19159             }
19160             if (newUserId >= 0) {
19161                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19162                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19163                 int count = profiles.size();
19164                 for (int i = 0; i < count; i++) {
19165                     int profileUserId = profiles.get(i).id;
19166                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19167                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19168                             | Intent.FLAG_RECEIVER_FOREGROUND);
19169                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19170                     broadcastIntentLocked(null, null, intent,
19171                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19172                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19173                 }
19174                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19175                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19176                         | Intent.FLAG_RECEIVER_FOREGROUND);
19177                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19178                 broadcastIntentLocked(null, null, intent,
19179                         null, null, 0, null, null,
19180                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19181                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19182             }
19183         } finally {
19184             Binder.restoreCallingIdentity(ident);
19185         }
19186     }
19187
19188     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19189             final int newUserId) {
19190         final int N = mUserSwitchObservers.beginBroadcast();
19191         if (N > 0) {
19192             final IRemoteCallback callback = new IRemoteCallback.Stub() {
19193                 int mCount = 0;
19194                 @Override
19195                 public void sendResult(Bundle data) throws RemoteException {
19196                     synchronized (ActivityManagerService.this) {
19197                         if (mCurUserSwitchCallback == this) {
19198                             mCount++;
19199                             if (mCount == N) {
19200                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19201                             }
19202                         }
19203                     }
19204                 }
19205             };
19206             synchronized (this) {
19207                 uss.switching = true;
19208                 mCurUserSwitchCallback = callback;
19209             }
19210             for (int i=0; i<N; i++) {
19211                 try {
19212                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19213                             newUserId, callback);
19214                 } catch (RemoteException e) {
19215                 }
19216             }
19217         } else {
19218             synchronized (this) {
19219                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19220             }
19221         }
19222         mUserSwitchObservers.finishBroadcast();
19223     }
19224
19225     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19226         synchronized (this) {
19227             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19228             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19229         }
19230     }
19231
19232     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19233         mCurUserSwitchCallback = null;
19234         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19235         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19236                 oldUserId, newUserId, uss));
19237     }
19238
19239     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19240         synchronized (this) {
19241             if (foreground) {
19242                 moveUserToForeground(uss, oldUserId, newUserId);
19243             }
19244         }
19245
19246         completeSwitchAndInitalize(uss, newUserId, true, false);
19247     }
19248
19249     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19250         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19251         if (homeInFront) {
19252             startHomeActivityLocked(newUserId, "moveUserToFroreground");
19253         } else {
19254             mStackSupervisor.resumeTopActivitiesLocked();
19255         }
19256         EventLogTags.writeAmSwitchUser(newUserId);
19257         getUserManagerLocked().userForeground(newUserId);
19258         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19259     }
19260
19261     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19262         completeSwitchAndInitalize(uss, newUserId, false, true);
19263     }
19264
19265     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19266             boolean clearInitializing, boolean clearSwitching) {
19267         boolean unfrozen = false;
19268         synchronized (this) {
19269             if (clearInitializing) {
19270                 uss.initializing = false;
19271                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19272             }
19273             if (clearSwitching) {
19274                 uss.switching = false;
19275             }
19276             if (!uss.switching && !uss.initializing) {
19277                 mWindowManager.stopFreezingScreen();
19278                 unfrozen = true;
19279             }
19280         }
19281         if (unfrozen) {
19282             final int N = mUserSwitchObservers.beginBroadcast();
19283             for (int i=0; i<N; i++) {
19284                 try {
19285                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19286                 } catch (RemoteException e) {
19287                 }
19288             }
19289             mUserSwitchObservers.finishBroadcast();
19290         }
19291         stopGuestUserIfBackground();
19292     }
19293
19294     /**
19295      * Stops the guest user if it has gone to the background.
19296      */
19297     private void stopGuestUserIfBackground() {
19298         synchronized (this) {
19299             final int num = mUserLru.size();
19300             for (int i = 0; i < num; i++) {
19301                 Integer oldUserId = mUserLru.get(i);
19302                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19303                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19304                         || oldUss.mState == UserStartedState.STATE_STOPPING
19305                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19306                     continue;
19307                 }
19308                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19309                 if (userInfo.isGuest()) {
19310                     // This is a user to be stopped.
19311                     stopUserLocked(oldUserId, null);
19312                     break;
19313                 }
19314             }
19315         }
19316     }
19317
19318     void scheduleStartProfilesLocked() {
19319         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19320             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19321                     DateUtils.SECOND_IN_MILLIS);
19322         }
19323     }
19324
19325     void startProfilesLocked() {
19326         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19327         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19328                 mCurrentUserId, false /* enabledOnly */);
19329         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19330         for (UserInfo user : profiles) {
19331             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19332                     && user.id != mCurrentUserId) {
19333                 toStart.add(user);
19334             }
19335         }
19336         final int n = toStart.size();
19337         int i = 0;
19338         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19339             startUserInBackground(toStart.get(i).id);
19340         }
19341         if (i < n) {
19342             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19343         }
19344     }
19345
19346     void finishUserBoot(UserStartedState uss) {
19347         synchronized (this) {
19348             if (uss.mState == UserStartedState.STATE_BOOTING
19349                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19350                 uss.mState = UserStartedState.STATE_RUNNING;
19351                 final int userId = uss.mHandle.getIdentifier();
19352                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19353                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19354                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19355                 broadcastIntentLocked(null, null, intent,
19356                         null, null, 0, null, null,
19357                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19358                         true, false, MY_PID, Process.SYSTEM_UID, userId);
19359             }
19360         }
19361     }
19362
19363     void finishUserSwitch(UserStartedState uss) {
19364         synchronized (this) {
19365             finishUserBoot(uss);
19366
19367             startProfilesLocked();
19368
19369             int num = mUserLru.size();
19370             int i = 0;
19371             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19372                 Integer oldUserId = mUserLru.get(i);
19373                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19374                 if (oldUss == null) {
19375                     // Shouldn't happen, but be sane if it does.
19376                     mUserLru.remove(i);
19377                     num--;
19378                     continue;
19379                 }
19380                 if (oldUss.mState == UserStartedState.STATE_STOPPING
19381                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19382                     // This user is already stopping, doesn't count.
19383                     num--;
19384                     i++;
19385                     continue;
19386                 }
19387                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19388                     // Owner and current can't be stopped, but count as running.
19389                     i++;
19390                     continue;
19391                 }
19392                 // This is a user to be stopped.
19393                 stopUserLocked(oldUserId, null);
19394                 num--;
19395                 i++;
19396             }
19397         }
19398     }
19399
19400     @Override
19401     public int stopUser(final int userId, final IStopUserCallback callback) {
19402         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19403                 != PackageManager.PERMISSION_GRANTED) {
19404             String msg = "Permission Denial: switchUser() from pid="
19405                     + Binder.getCallingPid()
19406                     + ", uid=" + Binder.getCallingUid()
19407                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19408             Slog.w(TAG, msg);
19409             throw new SecurityException(msg);
19410         }
19411         if (userId <= 0) {
19412             throw new IllegalArgumentException("Can't stop primary user " + userId);
19413         }
19414         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19415         synchronized (this) {
19416             return stopUserLocked(userId, callback);
19417         }
19418     }
19419
19420     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19421         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19422         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19423             return ActivityManager.USER_OP_IS_CURRENT;
19424         }
19425
19426         final UserStartedState uss = mStartedUsers.get(userId);
19427         if (uss == null) {
19428             // User is not started, nothing to do...  but we do need to
19429             // callback if requested.
19430             if (callback != null) {
19431                 mHandler.post(new Runnable() {
19432                     @Override
19433                     public void run() {
19434                         try {
19435                             callback.userStopped(userId);
19436                         } catch (RemoteException e) {
19437                         }
19438                     }
19439                 });
19440             }
19441             return ActivityManager.USER_OP_SUCCESS;
19442         }
19443
19444         if (callback != null) {
19445             uss.mStopCallbacks.add(callback);
19446         }
19447
19448         if (uss.mState != UserStartedState.STATE_STOPPING
19449                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19450             uss.mState = UserStartedState.STATE_STOPPING;
19451             updateStartedUserArrayLocked();
19452
19453             long ident = Binder.clearCallingIdentity();
19454             try {
19455                 // We are going to broadcast ACTION_USER_STOPPING and then
19456                 // once that is done send a final ACTION_SHUTDOWN and then
19457                 // stop the user.
19458                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19459                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19460                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19461                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19462                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19463                 // This is the result receiver for the final shutdown broadcast.
19464                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19465                     @Override
19466                     public void performReceive(Intent intent, int resultCode, String data,
19467                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19468                         finishUserStop(uss);
19469                     }
19470                 };
19471                 // This is the result receiver for the initial stopping broadcast.
19472                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19473                     @Override
19474                     public void performReceive(Intent intent, int resultCode, String data,
19475                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19476                         // On to the next.
19477                         synchronized (ActivityManagerService.this) {
19478                             if (uss.mState != UserStartedState.STATE_STOPPING) {
19479                                 // Whoops, we are being started back up.  Abort, abort!
19480                                 return;
19481                             }
19482                             uss.mState = UserStartedState.STATE_SHUTDOWN;
19483                         }
19484                         mBatteryStatsService.noteEvent(
19485                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19486                                 Integer.toString(userId), userId);
19487                         mSystemServiceManager.stopUser(userId);
19488                         broadcastIntentLocked(null, null, shutdownIntent,
19489                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19490                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
19491                     }
19492                 };
19493                 // Kick things off.
19494                 broadcastIntentLocked(null, null, stoppingIntent,
19495                         null, stoppingReceiver, 0, null, null,
19496                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19497                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19498             } finally {
19499                 Binder.restoreCallingIdentity(ident);
19500             }
19501         }
19502
19503         return ActivityManager.USER_OP_SUCCESS;
19504     }
19505
19506     void finishUserStop(UserStartedState uss) {
19507         final int userId = uss.mHandle.getIdentifier();
19508         boolean stopped;
19509         ArrayList<IStopUserCallback> callbacks;
19510         synchronized (this) {
19511             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19512             if (mStartedUsers.get(userId) != uss) {
19513                 stopped = false;
19514             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19515                 stopped = false;
19516             } else {
19517                 stopped = true;
19518                 // User can no longer run.
19519                 mStartedUsers.remove(userId);
19520                 mUserLru.remove(Integer.valueOf(userId));
19521                 updateStartedUserArrayLocked();
19522
19523                 // Clean up all state and processes associated with the user.
19524                 // Kill all the processes for the user.
19525                 forceStopUserLocked(userId, "finish user");
19526             }
19527
19528             // Explicitly remove the old information in mRecentTasks.
19529             removeRecentTasksForUserLocked(userId);
19530         }
19531
19532         for (int i=0; i<callbacks.size(); i++) {
19533             try {
19534                 if (stopped) callbacks.get(i).userStopped(userId);
19535                 else callbacks.get(i).userStopAborted(userId);
19536             } catch (RemoteException e) {
19537             }
19538         }
19539
19540         if (stopped) {
19541             mSystemServiceManager.cleanupUser(userId);
19542             synchronized (this) {
19543                 mStackSupervisor.removeUserLocked(userId);
19544             }
19545         }
19546     }
19547
19548     @Override
19549     public UserInfo getCurrentUser() {
19550         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19551                 != PackageManager.PERMISSION_GRANTED) && (
19552                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19553                 != PackageManager.PERMISSION_GRANTED)) {
19554             String msg = "Permission Denial: getCurrentUser() from pid="
19555                     + Binder.getCallingPid()
19556                     + ", uid=" + Binder.getCallingUid()
19557                     + " requires " + INTERACT_ACROSS_USERS;
19558             Slog.w(TAG, msg);
19559             throw new SecurityException(msg);
19560         }
19561         synchronized (this) {
19562             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19563             return getUserManagerLocked().getUserInfo(userId);
19564         }
19565     }
19566
19567     int getCurrentUserIdLocked() {
19568         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19569     }
19570
19571     @Override
19572     public boolean isUserRunning(int userId, boolean orStopped) {
19573         if (checkCallingPermission(INTERACT_ACROSS_USERS)
19574                 != PackageManager.PERMISSION_GRANTED) {
19575             String msg = "Permission Denial: isUserRunning() from pid="
19576                     + Binder.getCallingPid()
19577                     + ", uid=" + Binder.getCallingUid()
19578                     + " requires " + INTERACT_ACROSS_USERS;
19579             Slog.w(TAG, msg);
19580             throw new SecurityException(msg);
19581         }
19582         synchronized (this) {
19583             return isUserRunningLocked(userId, orStopped);
19584         }
19585     }
19586
19587     boolean isUserRunningLocked(int userId, boolean orStopped) {
19588         UserStartedState state = mStartedUsers.get(userId);
19589         if (state == null) {
19590             return false;
19591         }
19592         if (orStopped) {
19593             return true;
19594         }
19595         return state.mState != UserStartedState.STATE_STOPPING
19596                 && state.mState != UserStartedState.STATE_SHUTDOWN;
19597     }
19598
19599     @Override
19600     public int[] getRunningUserIds() {
19601         if (checkCallingPermission(INTERACT_ACROSS_USERS)
19602                 != PackageManager.PERMISSION_GRANTED) {
19603             String msg = "Permission Denial: isUserRunning() from pid="
19604                     + Binder.getCallingPid()
19605                     + ", uid=" + Binder.getCallingUid()
19606                     + " requires " + INTERACT_ACROSS_USERS;
19607             Slog.w(TAG, msg);
19608             throw new SecurityException(msg);
19609         }
19610         synchronized (this) {
19611             return mStartedUserArray;
19612         }
19613     }
19614
19615     private void updateStartedUserArrayLocked() {
19616         int num = 0;
19617         for (int i=0; i<mStartedUsers.size();  i++) {
19618             UserStartedState uss = mStartedUsers.valueAt(i);
19619             // This list does not include stopping users.
19620             if (uss.mState != UserStartedState.STATE_STOPPING
19621                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19622                 num++;
19623             }
19624         }
19625         mStartedUserArray = new int[num];
19626         num = 0;
19627         for (int i=0; i<mStartedUsers.size();  i++) {
19628             UserStartedState uss = mStartedUsers.valueAt(i);
19629             if (uss.mState != UserStartedState.STATE_STOPPING
19630                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19631                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
19632                 num++;
19633             }
19634         }
19635     }
19636
19637     @Override
19638     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19639         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19640                 != PackageManager.PERMISSION_GRANTED) {
19641             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19642                     + Binder.getCallingPid()
19643                     + ", uid=" + Binder.getCallingUid()
19644                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19645             Slog.w(TAG, msg);
19646             throw new SecurityException(msg);
19647         }
19648
19649         mUserSwitchObservers.register(observer);
19650     }
19651
19652     @Override
19653     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19654         mUserSwitchObservers.unregister(observer);
19655     }
19656
19657     private boolean userExists(int userId) {
19658         if (userId == 0) {
19659             return true;
19660         }
19661         UserManagerService ums = getUserManagerLocked();
19662         return ums != null ? (ums.getUserInfo(userId) != null) : false;
19663     }
19664
19665     int[] getUsersLocked() {
19666         UserManagerService ums = getUserManagerLocked();
19667         return ums != null ? ums.getUserIds() : new int[] { 0 };
19668     }
19669
19670     UserManagerService getUserManagerLocked() {
19671         if (mUserManager == null) {
19672             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19673             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19674         }
19675         return mUserManager;
19676     }
19677
19678     private int applyUserId(int uid, int userId) {
19679         return UserHandle.getUid(userId, uid);
19680     }
19681
19682     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19683         if (info == null) return null;
19684         ApplicationInfo newInfo = new ApplicationInfo(info);
19685         newInfo.uid = applyUserId(info.uid, userId);
19686         newInfo.dataDir = USER_DATA_DIR + userId + "/"
19687                 + info.packageName;
19688         return newInfo;
19689     }
19690
19691     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19692         if (aInfo == null
19693                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19694             return aInfo;
19695         }
19696
19697         ActivityInfo info = new ActivityInfo(aInfo);
19698         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19699         return info;
19700     }
19701
19702     private final class LocalService extends ActivityManagerInternal {
19703         @Override
19704         public void onWakefulnessChanged(int wakefulness) {
19705             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19706         }
19707
19708         @Override
19709         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19710                 String processName, String abiOverride, int uid, Runnable crashHandler) {
19711             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19712                     processName, abiOverride, uid, crashHandler);
19713         }
19714     }
19715
19716     /**
19717      * An implementation of IAppTask, that allows an app to manage its own tasks via
19718      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19719      * only the process that calls getAppTasks() can call the AppTask methods.
19720      */
19721     class AppTaskImpl extends IAppTask.Stub {
19722         private int mTaskId;
19723         private int mCallingUid;
19724
19725         public AppTaskImpl(int taskId, int callingUid) {
19726             mTaskId = taskId;
19727             mCallingUid = callingUid;
19728         }
19729
19730         private void checkCaller() {
19731             if (mCallingUid != Binder.getCallingUid()) {
19732                 throw new SecurityException("Caller " + mCallingUid
19733                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19734             }
19735         }
19736
19737         @Override
19738         public void finishAndRemoveTask() {
19739             checkCaller();
19740
19741             synchronized (ActivityManagerService.this) {
19742                 long origId = Binder.clearCallingIdentity();
19743                 try {
19744                     if (!removeTaskByIdLocked(mTaskId, false)) {
19745                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19746                     }
19747                 } finally {
19748                     Binder.restoreCallingIdentity(origId);
19749                 }
19750             }
19751         }
19752
19753         @Override
19754         public ActivityManager.RecentTaskInfo getTaskInfo() {
19755             checkCaller();
19756
19757             synchronized (ActivityManagerService.this) {
19758                 long origId = Binder.clearCallingIdentity();
19759                 try {
19760                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19761                     if (tr == null) {
19762                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19763                     }
19764                     return createRecentTaskInfoFromTaskRecord(tr);
19765                 } finally {
19766                     Binder.restoreCallingIdentity(origId);
19767                 }
19768             }
19769         }
19770
19771         @Override
19772         public void moveToFront() {
19773             checkCaller();
19774             // Will bring task to front if it already has a root activity.
19775             startActivityFromRecentsInner(mTaskId, null);
19776         }
19777
19778         @Override
19779         public int startActivity(IBinder whoThread, String callingPackage,
19780                 Intent intent, String resolvedType, Bundle options) {
19781             checkCaller();
19782
19783             int callingUser = UserHandle.getCallingUserId();
19784             TaskRecord tr;
19785             IApplicationThread appThread;
19786             synchronized (ActivityManagerService.this) {
19787                 tr = recentTaskForIdLocked(mTaskId);
19788                 if (tr == null) {
19789                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19790                 }
19791                 appThread = ApplicationThreadNative.asInterface(whoThread);
19792                 if (appThread == null) {
19793                     throw new IllegalArgumentException("Bad app thread " + appThread);
19794                 }
19795             }
19796             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19797                     resolvedType, null, null, null, null, 0, 0, null, null,
19798                     null, options, callingUser, null, tr);
19799         }
19800
19801         @Override
19802         public void setExcludeFromRecents(boolean exclude) {
19803             checkCaller();
19804
19805             synchronized (ActivityManagerService.this) {
19806                 long origId = Binder.clearCallingIdentity();
19807                 try {
19808                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19809                     if (tr == null) {
19810                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19811                     }
19812                     Intent intent = tr.getBaseIntent();
19813                     if (exclude) {
19814                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19815                     } else {
19816                         intent.setFlags(intent.getFlags()
19817                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19818                     }
19819                 } finally {
19820                     Binder.restoreCallingIdentity(origId);
19821                 }
19822             }
19823         }
19824     }
19825 }