OSDN Git Service

am 1cf21e44: DO NOT MERGE - Backport of ag/748165 to klp-dev Security patch level...
[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
34 import android.Manifest;
35 import android.app.AppOpsManager;
36 import android.app.ApplicationThreadNative;
37 import android.app.IActivityContainer;
38 import android.app.IActivityContainerCallback;
39 import android.app.IAppTask;
40 import android.app.ProfilerInfo;
41 import android.app.admin.DevicePolicyManager;
42 import android.app.usage.UsageEvents;
43 import android.app.usage.UsageStatsManagerInternal;
44 import android.appwidget.AppWidgetManager;
45 import android.content.res.Resources;
46 import android.graphics.Bitmap;
47 import android.graphics.Point;
48 import android.graphics.Rect;
49 import android.os.BatteryStats;
50 import android.os.PersistableBundle;
51 import android.os.storage.IMountService;
52 import android.os.storage.StorageManager;
53 import android.service.voice.IVoiceInteractionSession;
54 import android.util.ArrayMap;
55 import android.util.ArraySet;
56 import android.util.SparseIntArray;
57
58 import android.view.Display;
59 import com.android.internal.R;
60 import com.android.internal.annotations.GuardedBy;
61 import com.android.internal.app.IAppOpsService;
62 import com.android.internal.app.IVoiceInteractor;
63 import com.android.internal.app.ProcessMap;
64 import com.android.internal.app.ProcessStats;
65 import com.android.internal.content.PackageMonitor;
66 import com.android.internal.os.BackgroundThread;
67 import com.android.internal.os.BatteryStatsImpl;
68 import com.android.internal.os.ProcessCpuTracker;
69 import com.android.internal.os.TransferPipe;
70 import com.android.internal.os.Zygote;
71 import com.android.internal.util.FastPrintWriter;
72 import com.android.internal.util.FastXmlSerializer;
73 import com.android.internal.util.MemInfoReader;
74 import com.android.internal.util.Preconditions;
75 import com.android.server.AppOpsService;
76 import com.android.server.AttributeCache;
77 import com.android.server.IntentResolver;
78 import com.android.server.LocalServices;
79 import com.android.server.ServiceThread;
80 import com.android.server.SystemService;
81 import com.android.server.SystemServiceManager;
82 import com.android.server.Watchdog;
83 import com.android.server.am.ActivityStack.ActivityState;
84 import com.android.server.firewall.IntentFirewall;
85 import com.android.server.pm.UserManagerService;
86 import com.android.server.wm.AppTransition;
87 import com.android.server.wm.WindowManagerService;
88 import com.google.android.collect.Lists;
89 import com.google.android.collect.Maps;
90
91 import libcore.io.IoUtils;
92
93 import org.xmlpull.v1.XmlPullParser;
94 import org.xmlpull.v1.XmlPullParserException;
95 import org.xmlpull.v1.XmlSerializer;
96
97 import android.app.Activity;
98 import android.app.ActivityManager;
99 import android.app.ActivityManager.RunningTaskInfo;
100 import android.app.ActivityManager.StackInfo;
101 import android.app.ActivityManagerInternal;
102 import android.app.ActivityManagerNative;
103 import android.app.ActivityOptions;
104 import android.app.ActivityThread;
105 import android.app.AlertDialog;
106 import android.app.AppGlobals;
107 import android.app.ApplicationErrorReport;
108 import android.app.Dialog;
109 import android.app.IActivityController;
110 import android.app.IApplicationThread;
111 import android.app.IInstrumentationWatcher;
112 import android.app.INotificationManager;
113 import android.app.IProcessObserver;
114 import android.app.IServiceConnection;
115 import android.app.IStopUserCallback;
116 import android.app.IUiAutomationConnection;
117 import android.app.IUserSwitchObserver;
118 import android.app.Instrumentation;
119 import android.app.Notification;
120 import android.app.NotificationManager;
121 import android.app.PendingIntent;
122 import android.app.backup.IBackupManager;
123 import android.content.ActivityNotFoundException;
124 import android.content.BroadcastReceiver;
125 import android.content.ClipData;
126 import android.content.ComponentCallbacks2;
127 import android.content.ComponentName;
128 import android.content.ContentProvider;
129 import android.content.ContentResolver;
130 import android.content.Context;
131 import android.content.DialogInterface;
132 import android.content.IContentProvider;
133 import android.content.IIntentReceiver;
134 import android.content.IIntentSender;
135 import android.content.Intent;
136 import android.content.IntentFilter;
137 import android.content.IntentSender;
138 import android.content.pm.ActivityInfo;
139 import android.content.pm.ApplicationInfo;
140 import android.content.pm.ConfigurationInfo;
141 import android.content.pm.IPackageDataObserver;
142 import android.content.pm.IPackageManager;
143 import android.content.pm.InstrumentationInfo;
144 import android.content.pm.PackageInfo;
145 import android.content.pm.PackageManager;
146 import android.content.pm.ParceledListSlice;
147 import android.content.pm.UserInfo;
148 import android.content.pm.PackageManager.NameNotFoundException;
149 import android.content.pm.PathPermission;
150 import android.content.pm.ProviderInfo;
151 import android.content.pm.ResolveInfo;
152 import android.content.pm.ServiceInfo;
153 import android.content.res.CompatibilityInfo;
154 import android.content.res.Configuration;
155 import android.net.Proxy;
156 import android.net.ProxyInfo;
157 import android.net.Uri;
158 import android.os.Binder;
159 import android.os.Build;
160 import android.os.Bundle;
161 import android.os.Debug;
162 import android.os.DropBoxManager;
163 import android.os.Environment;
164 import android.os.FactoryTest;
165 import android.os.FileObserver;
166 import android.os.FileUtils;
167 import android.os.Handler;
168 import android.os.IBinder;
169 import android.os.IPermissionController;
170 import android.os.IRemoteCallback;
171 import android.os.IUserManager;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PowerManagerInternal;
177 import android.os.Process;
178 import android.os.RemoteCallbackList;
179 import android.os.RemoteException;
180 import android.os.SELinux;
181 import android.os.ServiceManager;
182 import android.os.StrictMode;
183 import android.os.SystemClock;
184 import android.os.SystemProperties;
185 import android.os.UpdateLock;
186 import android.os.UserHandle;
187 import android.os.UserManager;
188 import android.provider.Settings;
189 import android.text.format.DateUtils;
190 import android.text.format.Time;
191 import android.util.AtomicFile;
192 import android.util.EventLog;
193 import android.util.Log;
194 import android.util.Pair;
195 import android.util.PrintWriterPrinter;
196 import android.util.Slog;
197 import android.util.SparseArray;
198 import android.util.TimeUtils;
199 import android.util.Xml;
200 import android.view.Gravity;
201 import android.view.LayoutInflater;
202 import android.view.View;
203 import android.view.WindowManager;
204 import dalvik.system.VMRuntime;
205
206 import java.io.BufferedInputStream;
207 import java.io.BufferedOutputStream;
208 import java.io.DataInputStream;
209 import java.io.DataOutputStream;
210 import java.io.File;
211 import java.io.FileDescriptor;
212 import java.io.FileInputStream;
213 import java.io.FileNotFoundException;
214 import java.io.FileOutputStream;
215 import java.io.IOException;
216 import java.io.InputStreamReader;
217 import java.io.PrintWriter;
218 import java.io.StringWriter;
219 import java.lang.ref.WeakReference;
220 import java.util.ArrayList;
221 import java.util.Arrays;
222 import java.util.Collections;
223 import java.util.Comparator;
224 import java.util.HashMap;
225 import java.util.HashSet;
226 import java.util.Iterator;
227 import java.util.List;
228 import java.util.Locale;
229 import java.util.Map;
230 import java.util.Set;
231 import java.util.concurrent.atomic.AtomicBoolean;
232 import java.util.concurrent.atomic.AtomicLong;
233
234 public final class ActivityManagerService extends ActivityManagerNative
235         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
236
237     private static final String USER_DATA_DIR = "/data/user/";
238     // File that stores last updated system version and called preboot receivers
239     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
240
241     static final String TAG = "ActivityManager";
242     static final String TAG_MU = "ActivityManagerServiceMU";
243     static final boolean DEBUG = false;
244     static final boolean localLOGV = DEBUG;
245     static final boolean DEBUG_BACKUP = localLOGV || false;
246     static final boolean DEBUG_BROADCAST = localLOGV || false;
247     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249     static final boolean DEBUG_CLEANUP = localLOGV || false;
250     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251     static final boolean DEBUG_FOCUS = false;
252     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253     static final boolean DEBUG_MU = localLOGV || false;
254     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255     static final boolean DEBUG_LRU = localLOGV || false;
256     static final boolean DEBUG_PAUSE = localLOGV || false;
257     static final boolean DEBUG_POWER = localLOGV || false;
258     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260     static final boolean DEBUG_PROCESSES = localLOGV || false;
261     static final boolean DEBUG_PROVIDER = localLOGV || false;
262     static final boolean DEBUG_RESULTS = localLOGV || false;
263     static final boolean DEBUG_SERVICE = localLOGV || false;
264     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265     static final boolean DEBUG_STACK = localLOGV || false;
266     static final boolean DEBUG_SWITCH = localLOGV || false;
267     static final boolean DEBUG_TASKS = localLOGV || false;
268     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269     static final boolean DEBUG_TRANSITION = localLOGV || false;
270     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272     static final boolean DEBUG_VISBILITY = localLOGV || false;
273     static final boolean DEBUG_PSS = localLOGV || false;
274     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275     static final boolean DEBUG_RECENTS = localLOGV || false;
276     static final boolean VALIDATE_TOKENS = false;
277     static final boolean SHOW_ACTIVITY_START_TIME = true;
278
279     // Control over CPU and battery monitoring.
280     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
281     static final boolean MONITOR_CPU_USAGE = true;
282     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
283     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
284     static final boolean MONITOR_THREAD_CPU_USAGE = false;
285
286     // The flags that are set for all calls we make to the package manager.
287     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
288
289     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
290
291     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
292
293     // Maximum number recent bitmaps to keep in memory.
294     static final int MAX_RECENT_BITMAPS = 5;
295
296     // Amount of time after a call to stopAppSwitches() during which we will
297     // prevent further untrusted switches from happening.
298     static final long APP_SWITCH_DELAY_TIME = 5*1000;
299
300     // How long we wait for a launched process to attach to the activity manager
301     // before we decide it's never going to come up for real.
302     static final int PROC_START_TIMEOUT = 10*1000;
303
304     // How long we wait for a launched process to attach to the activity manager
305     // before we decide it's never going to come up for real, when the process was
306     // started with a wrapper for instrumentation (such as Valgrind) because it
307     // could take much longer than usual.
308     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
309
310     // How long to wait after going idle before forcing apps to GC.
311     static final int GC_TIMEOUT = 5*1000;
312
313     // The minimum amount of time between successive GC requests for a process.
314     static final int GC_MIN_INTERVAL = 60*1000;
315
316     // The minimum amount of time between successive PSS requests for a process.
317     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
318
319     // The minimum amount of time between successive PSS requests for a process
320     // when the request is due to the memory state being lowered.
321     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
322
323     // The rate at which we check for apps using excessive power -- 15 mins.
324     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
325
326     // The minimum sample duration we will allow before deciding we have
327     // enough data on wake locks to start killing things.
328     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
329
330     // The minimum sample duration we will allow before deciding we have
331     // enough data on CPU usage to start killing things.
332     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
333
334     // How long we allow a receiver to run before giving up on it.
335     static final int BROADCAST_FG_TIMEOUT = 10*1000;
336     static final int BROADCAST_BG_TIMEOUT = 60*1000;
337
338     // How long we wait until we timeout on key dispatching.
339     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
340
341     // How long we wait until we timeout on key dispatching during instrumentation.
342     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
343
344     // Amount of time we wait for observers to handle a user switch before
345     // giving up on them and unfreezing the screen.
346     static final int USER_SWITCH_TIMEOUT = 2*1000;
347
348     // Maximum number of users we allow to be running at a time.
349     static final int MAX_RUNNING_USERS = 3;
350
351     // How long to wait in getAssistContextExtras for the activity and foreground services
352     // to respond with the result.
353     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
354
355     // Maximum number of persisted Uri grants a package is allowed
356     static final int MAX_PERSISTED_URI_GRANTS = 128;
357
358     static final int MY_PID = Process.myPid();
359
360     static final String[] EMPTY_STRING_ARRAY = new String[0];
361
362     // How many bytes to write into the dropbox log before truncating
363     static final int DROPBOX_MAX_SIZE = 256 * 1024;
364
365     // Access modes for handleIncomingUser.
366     static final int ALLOW_NON_FULL = 0;
367     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368     static final int ALLOW_FULL_ONLY = 2;
369
370     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
371
372     /** All system services */
373     SystemServiceManager mSystemServiceManager;
374
375     /** Run all ActivityStacks through this */
376     ActivityStackSupervisor mStackSupervisor;
377
378     public IntentFirewall mIntentFirewall;
379
380     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
381     // default actuion automatically.  Important for devices without direct input
382     // devices.
383     private boolean mShowDialogs = true;
384
385     BroadcastQueue mFgBroadcastQueue;
386     BroadcastQueue mBgBroadcastQueue;
387     // Convenient for easy iteration over the queues. Foreground is first
388     // so that dispatch of foreground broadcasts gets precedence.
389     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
390
391     BroadcastQueue broadcastQueueForIntent(Intent intent) {
392         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
393         if (DEBUG_BACKGROUND_BROADCAST) {
394             Slog.i(TAG, "Broadcast intent " + intent + " on "
395                     + (isFg ? "foreground" : "background")
396                     + " queue");
397         }
398         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
399     }
400
401     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
402         for (BroadcastQueue queue : mBroadcastQueues) {
403             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
404             if (r != null) {
405                 return r;
406             }
407         }
408         return null;
409     }
410
411     /**
412      * Activity we have told the window manager to have key focus.
413      */
414     ActivityRecord mFocusedActivity = null;
415
416     /**
417      * List of intents that were used to start the most recent tasks.
418      */
419     ArrayList<TaskRecord> mRecentTasks;
420     ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
421
422     /**
423      * For addAppTask: cached of the last activity component that was added.
424      */
425     ComponentName mLastAddedTaskComponent;
426
427     /**
428      * For addAppTask: cached of the last activity uid that was added.
429      */
430     int mLastAddedTaskUid;
431
432     /**
433      * For addAppTask: cached of the last ActivityInfo that was added.
434      */
435     ActivityInfo mLastAddedTaskActivity;
436
437     public class PendingAssistExtras extends Binder implements Runnable {
438         public final ActivityRecord activity;
439         public final Bundle extras;
440         public final Intent intent;
441         public final String hint;
442         public final int userHandle;
443         public boolean haveResult = false;
444         public Bundle result = null;
445         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
446                 String _hint, int _userHandle) {
447             activity = _activity;
448             extras = _extras;
449             intent = _intent;
450             hint = _hint;
451             userHandle = _userHandle;
452         }
453         @Override
454         public void run() {
455             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
456             synchronized (this) {
457                 haveResult = true;
458                 notifyAll();
459             }
460         }
461     }
462
463     final ArrayList<PendingAssistExtras> mPendingAssistExtras
464             = new ArrayList<PendingAssistExtras>();
465
466     /**
467      * Process management.
468      */
469     final ProcessList mProcessList = new ProcessList();
470
471     /**
472      * All of the applications we currently have running organized by name.
473      * The keys are strings of the application package name (as
474      * returned by the package manager), and the keys are ApplicationRecord
475      * objects.
476      */
477     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
478
479     /**
480      * Tracking long-term execution of processes to look for abuse and other
481      * bad app behavior.
482      */
483     final ProcessStatsService mProcessStats;
484
485     /**
486      * The currently running isolated processes.
487      */
488     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
489
490     /**
491      * Counter for assigning isolated process uids, to avoid frequently reusing the
492      * same ones.
493      */
494     int mNextIsolatedProcessUid = 0;
495
496     /**
497      * The currently running heavy-weight process, if any.
498      */
499     ProcessRecord mHeavyWeightProcess = null;
500
501     /**
502      * The last time that various processes have crashed.
503      */
504     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
505
506     /**
507      * Information about a process that is currently marked as bad.
508      */
509     static final class BadProcessInfo {
510         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
511             this.time = time;
512             this.shortMsg = shortMsg;
513             this.longMsg = longMsg;
514             this.stack = stack;
515         }
516
517         final long time;
518         final String shortMsg;
519         final String longMsg;
520         final String stack;
521     }
522
523     /**
524      * Set of applications that we consider to be bad, and will reject
525      * incoming broadcasts from (which the user has no control over).
526      * Processes are added to this set when they have crashed twice within
527      * a minimum amount of time; they are removed from it when they are
528      * later restarted (hopefully due to some user action).  The value is the
529      * time it was added to the list.
530      */
531     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
532
533     /**
534      * All of the processes we currently have running organized by pid.
535      * The keys are the pid running the application.
536      *
537      * <p>NOTE: This object is protected by its own lock, NOT the global
538      * activity manager lock!
539      */
540     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
541
542     /**
543      * All of the processes that have been forced to be foreground.  The key
544      * is the pid of the caller who requested it (we hold a death
545      * link on it).
546      */
547     abstract class ForegroundToken implements IBinder.DeathRecipient {
548         int pid;
549         IBinder token;
550     }
551     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
552
553     /**
554      * List of records for processes that someone had tried to start before the
555      * system was ready.  We don't start them at that point, but ensure they
556      * are started by the time booting is complete.
557      */
558     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
559
560     /**
561      * List of persistent applications that are in the process
562      * of being started.
563      */
564     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
565
566     /**
567      * Processes that are being forcibly torn down.
568      */
569     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
570
571     /**
572      * List of running applications, sorted by recent usage.
573      * The first entry in the list is the least recently used.
574      */
575     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
576
577     /**
578      * Where in mLruProcesses that the processes hosting activities start.
579      */
580     int mLruProcessActivityStart = 0;
581
582     /**
583      * Where in mLruProcesses that the processes hosting services start.
584      * This is after (lower index) than mLruProcessesActivityStart.
585      */
586     int mLruProcessServiceStart = 0;
587
588     /**
589      * List of processes that should gc as soon as things are idle.
590      */
591     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
592
593     /**
594      * Processes we want to collect PSS data from.
595      */
596     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
597
598     /**
599      * Last time we requested PSS data of all processes.
600      */
601     long mLastFullPssTime = SystemClock.uptimeMillis();
602
603     /**
604      * If set, the next time we collect PSS data we should do a full collection
605      * with data from native processes and the kernel.
606      */
607     boolean mFullPssPending = false;
608
609     /**
610      * This is the process holding what we currently consider to be
611      * the "home" activity.
612      */
613     ProcessRecord mHomeProcess;
614
615     /**
616      * This is the process holding the activity the user last visited that
617      * is in a different process from the one they are currently in.
618      */
619     ProcessRecord mPreviousProcess;
620
621     /**
622      * The time at which the previous process was last visible.
623      */
624     long mPreviousProcessVisibleTime;
625
626     /**
627      * Which uses have been started, so are allowed to run code.
628      */
629     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
630
631     /**
632      * LRU list of history of current users.  Most recently current is at the end.
633      */
634     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
635
636     /**
637      * Constant array of the users that are currently started.
638      */
639     int[] mStartedUserArray = new int[] { 0 };
640
641     /**
642      * Registered observers of the user switching mechanics.
643      */
644     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
645             = new RemoteCallbackList<IUserSwitchObserver>();
646
647     /**
648      * Currently active user switch.
649      */
650     Object mCurUserSwitchCallback;
651
652     /**
653      * Packages that the user has asked to have run in screen size
654      * compatibility mode instead of filling the screen.
655      */
656     final CompatModePackages mCompatModePackages;
657
658     /**
659      * Set of IntentSenderRecord objects that are currently active.
660      */
661     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
662             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
663
664     /**
665      * Fingerprints (hashCode()) of stack traces that we've
666      * already logged DropBox entries for.  Guarded by itself.  If
667      * something (rogue user app) forces this over
668      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
669      */
670     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
671     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
672
673     /**
674      * Strict Mode background batched logging state.
675      *
676      * The string buffer is guarded by itself, and its lock is also
677      * used to determine if another batched write is already
678      * in-flight.
679      */
680     private final StringBuilder mStrictModeBuffer = new StringBuilder();
681
682     /**
683      * Keeps track of all IIntentReceivers that have been registered for
684      * broadcasts.  Hash keys are the receiver IBinder, hash value is
685      * a ReceiverList.
686      */
687     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
688             new HashMap<IBinder, ReceiverList>();
689
690     /**
691      * Resolver for broadcast intents to registered receivers.
692      * Holds BroadcastFilter (subclass of IntentFilter).
693      */
694     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
695             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
696         @Override
697         protected boolean allowFilterResult(
698                 BroadcastFilter filter, List<BroadcastFilter> dest) {
699             IBinder target = filter.receiverList.receiver.asBinder();
700             for (int i=dest.size()-1; i>=0; i--) {
701                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
702                     return false;
703                 }
704             }
705             return true;
706         }
707
708         @Override
709         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
710             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
711                     || userId == filter.owningUserId) {
712                 return super.newResult(filter, match, userId);
713             }
714             return null;
715         }
716
717         @Override
718         protected BroadcastFilter[] newArray(int size) {
719             return new BroadcastFilter[size];
720         }
721
722         @Override
723         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
724             return packageName.equals(filter.packageName);
725         }
726     };
727
728     /**
729      * State of all active sticky broadcasts per user.  Keys are the action of the
730      * sticky Intent, values are an ArrayList of all broadcasted intents with
731      * that action (which should usually be one).  The SparseArray is keyed
732      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
733      * for stickies that are sent to all users.
734      */
735     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
736             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
737
738     final ActiveServices mServices;
739
740     /**
741      * Backup/restore process management
742      */
743     String mBackupAppName = null;
744     BackupRecord mBackupTarget = null;
745
746     final ProviderMap mProviderMap;
747
748     /**
749      * List of content providers who have clients waiting for them.  The
750      * application is currently being launched and the provider will be
751      * removed from this list once it is published.
752      */
753     final ArrayList<ContentProviderRecord> mLaunchingProviders
754             = new ArrayList<ContentProviderRecord>();
755
756     /**
757      * File storing persisted {@link #mGrantedUriPermissions}.
758      */
759     private final AtomicFile mGrantFile;
760
761     /** XML constants used in {@link #mGrantFile} */
762     private static final String TAG_URI_GRANTS = "uri-grants";
763     private static final String TAG_URI_GRANT = "uri-grant";
764     private static final String ATTR_USER_HANDLE = "userHandle";
765     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
766     private static final String ATTR_TARGET_USER_ID = "targetUserId";
767     private static final String ATTR_SOURCE_PKG = "sourcePkg";
768     private static final String ATTR_TARGET_PKG = "targetPkg";
769     private static final String ATTR_URI = "uri";
770     private static final String ATTR_MODE_FLAGS = "modeFlags";
771     private static final String ATTR_CREATED_TIME = "createdTime";
772     private static final String ATTR_PREFIX = "prefix";
773
774     /**
775      * Global set of specific {@link Uri} permissions that have been granted.
776      * This optimized lookup structure maps from {@link UriPermission#targetUid}
777      * to {@link UriPermission#uri} to {@link UriPermission}.
778      */
779     @GuardedBy("this")
780     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
781             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
782
783     public static class GrantUri {
784         public final int sourceUserId;
785         public final Uri uri;
786         public boolean prefix;
787
788         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
789             this.sourceUserId = sourceUserId;
790             this.uri = uri;
791             this.prefix = prefix;
792         }
793
794         @Override
795         public int hashCode() {
796             return toString().hashCode();
797         }
798
799         @Override
800         public boolean equals(Object o) {
801             if (o instanceof GrantUri) {
802                 GrantUri other = (GrantUri) o;
803                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
804                         && prefix == other.prefix;
805             }
806             return false;
807         }
808
809         @Override
810         public String toString() {
811             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
812             if (prefix) result += " [prefix]";
813             return result;
814         }
815
816         public String toSafeString() {
817             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
818             if (prefix) result += " [prefix]";
819             return result;
820         }
821
822         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
823             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
824                     ContentProvider.getUriWithoutUserId(uri), false);
825         }
826     }
827
828     CoreSettingsObserver mCoreSettingsObserver;
829
830     /**
831      * Thread-local storage used to carry caller permissions over through
832      * indirect content-provider access.
833      */
834     private class Identity {
835         public int pid;
836         public int uid;
837
838         Identity(int _pid, int _uid) {
839             pid = _pid;
840             uid = _uid;
841         }
842     }
843
844     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
845
846     /**
847      * All information we have collected about the runtime performance of
848      * any user id that can impact battery performance.
849      */
850     final BatteryStatsService mBatteryStatsService;
851
852     /**
853      * Information about component usage
854      */
855     UsageStatsManagerInternal mUsageStatsService;
856
857     /**
858      * Information about and control over application operations
859      */
860     final AppOpsService mAppOpsService;
861
862     /**
863      * Save recent tasks information across reboots.
864      */
865     final TaskPersister mTaskPersister;
866
867     /**
868      * Current configuration information.  HistoryRecord objects are given
869      * a reference to this object to indicate which configuration they are
870      * currently running in, so this object must be kept immutable.
871      */
872     Configuration mConfiguration = new Configuration();
873
874     /**
875      * Current sequencing integer of the configuration, for skipping old
876      * configurations.
877      */
878     int mConfigurationSeq = 0;
879
880     /**
881      * Hardware-reported OpenGLES version.
882      */
883     final int GL_ES_VERSION;
884
885     /**
886      * List of initialization arguments to pass to all processes when binding applications to them.
887      * For example, references to the commonly used services.
888      */
889     HashMap<String, IBinder> mAppBindArgs;
890
891     /**
892      * Temporary to avoid allocations.  Protected by main lock.
893      */
894     final StringBuilder mStringBuilder = new StringBuilder(256);
895
896     /**
897      * Used to control how we initialize the service.
898      */
899     ComponentName mTopComponent;
900     String mTopAction = Intent.ACTION_MAIN;
901     String mTopData;
902     boolean mProcessesReady = false;
903     boolean mSystemReady = false;
904     boolean mBooting = false;
905     boolean mCallFinishBooting = false;
906     boolean mBootAnimationComplete = false;
907     boolean mWaitingUpdate = false;
908     boolean mDidUpdate = false;
909     boolean mOnBattery = false;
910     boolean mLaunchWarningShown = false;
911
912     Context mContext;
913
914     int mFactoryTest;
915
916     boolean mCheckedForSetup;
917
918     /**
919      * The time at which we will allow normal application switches again,
920      * after a call to {@link #stopAppSwitches()}.
921      */
922     long mAppSwitchesAllowedTime;
923
924     /**
925      * This is set to true after the first switch after mAppSwitchesAllowedTime
926      * is set; any switches after that will clear the time.
927      */
928     boolean mDidAppSwitch;
929
930     /**
931      * Last time (in realtime) at which we checked for power usage.
932      */
933     long mLastPowerCheckRealtime;
934
935     /**
936      * Last time (in uptime) at which we checked for power usage.
937      */
938     long mLastPowerCheckUptime;
939
940     /**
941      * Set while we are wanting to sleep, to prevent any
942      * activities from being started/resumed.
943      */
944     private boolean mSleeping = false;
945
946     /**
947      * Set while we are running a voice interaction.  This overrides
948      * sleeping while it is active.
949      */
950     private boolean mRunningVoice = false;
951
952     /**
953      * State of external calls telling us if the device is awake or asleep.
954      */
955     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
956
957     /**
958      * State of external call telling us if the lock screen is shown.
959      */
960     private boolean mLockScreenShown = false;
961
962     /**
963      * Set if we are shutting down the system, similar to sleeping.
964      */
965     boolean mShuttingDown = false;
966
967     /**
968      * Current sequence id for oom_adj computation traversal.
969      */
970     int mAdjSeq = 0;
971
972     /**
973      * Current sequence id for process LRU updating.
974      */
975     int mLruSeq = 0;
976
977     /**
978      * Keep track of the non-cached/empty process we last found, to help
979      * determine how to distribute cached/empty processes next time.
980      */
981     int mNumNonCachedProcs = 0;
982
983     /**
984      * Keep track of the number of cached hidden procs, to balance oom adj
985      * distribution between those and empty procs.
986      */
987     int mNumCachedHiddenProcs = 0;
988
989     /**
990      * Keep track of the number of service processes we last found, to
991      * determine on the next iteration which should be B services.
992      */
993     int mNumServiceProcs = 0;
994     int mNewNumAServiceProcs = 0;
995     int mNewNumServiceProcs = 0;
996
997     /**
998      * Allow the current computed overall memory level of the system to go down?
999      * This is set to false when we are killing processes for reasons other than
1000      * memory management, so that the now smaller process list will not be taken as
1001      * an indication that memory is tighter.
1002      */
1003     boolean mAllowLowerMemLevel = false;
1004
1005     /**
1006      * The last computed memory level, for holding when we are in a state that
1007      * processes are going away for other reasons.
1008      */
1009     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1010
1011     /**
1012      * The last total number of process we have, to determine if changes actually look
1013      * like a shrinking number of process due to lower RAM.
1014      */
1015     int mLastNumProcesses;
1016
1017     /**
1018      * The uptime of the last time we performed idle maintenance.
1019      */
1020     long mLastIdleTime = SystemClock.uptimeMillis();
1021
1022     /**
1023      * Total time spent with RAM that has been added in the past since the last idle time.
1024      */
1025     long mLowRamTimeSinceLastIdle = 0;
1026
1027     /**
1028      * If RAM is currently low, when that horrible situation started.
1029      */
1030     long mLowRamStartTime = 0;
1031
1032     /**
1033      * For reporting to battery stats the current top application.
1034      */
1035     private String mCurResumedPackage = null;
1036     private int mCurResumedUid = -1;
1037
1038     /**
1039      * For reporting to battery stats the apps currently running foreground
1040      * service.  The ProcessMap is package/uid tuples; each of these contain
1041      * an array of the currently foreground processes.
1042      */
1043     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1044             = new ProcessMap<ArrayList<ProcessRecord>>();
1045
1046     /**
1047      * This is set if we had to do a delayed dexopt of an app before launching
1048      * it, to increase the ANR timeouts in that case.
1049      */
1050     boolean mDidDexOpt;
1051
1052     /**
1053      * Set if the systemServer made a call to enterSafeMode.
1054      */
1055     boolean mSafeMode;
1056
1057     String mDebugApp = null;
1058     boolean mWaitForDebugger = false;
1059     boolean mDebugTransient = false;
1060     String mOrigDebugApp = null;
1061     boolean mOrigWaitForDebugger = false;
1062     boolean mAlwaysFinishActivities = false;
1063     IActivityController mController = null;
1064     String mProfileApp = null;
1065     ProcessRecord mProfileProc = null;
1066     String mProfileFile;
1067     ParcelFileDescriptor mProfileFd;
1068     int mSamplingInterval = 0;
1069     boolean mAutoStopProfiler = false;
1070     int mProfileType = 0;
1071     String mOpenGlTraceApp = null;
1072
1073     static class ProcessChangeItem {
1074         static final int CHANGE_ACTIVITIES = 1<<0;
1075         static final int CHANGE_PROCESS_STATE = 1<<1;
1076         int changes;
1077         int uid;
1078         int pid;
1079         int processState;
1080         boolean foregroundActivities;
1081     }
1082
1083     final RemoteCallbackList<IProcessObserver> mProcessObservers
1084             = new RemoteCallbackList<IProcessObserver>();
1085     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1086
1087     final ArrayList<ProcessChangeItem> mPendingProcessChanges
1088             = new ArrayList<ProcessChangeItem>();
1089     final ArrayList<ProcessChangeItem> mAvailProcessChanges
1090             = new ArrayList<ProcessChangeItem>();
1091
1092     /**
1093      * Runtime CPU use collection thread.  This object's lock is used to
1094      * perform synchronization with the thread (notifying it to run).
1095      */
1096     final Thread mProcessCpuThread;
1097
1098     /**
1099      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1100      * Must acquire this object's lock when accessing it.
1101      * NOTE: this lock will be held while doing long operations (trawling
1102      * through all processes in /proc), so it should never be acquired by
1103      * any critical paths such as when holding the main activity manager lock.
1104      */
1105     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1106             MONITOR_THREAD_CPU_USAGE);
1107     final AtomicLong mLastCpuTime = new AtomicLong(0);
1108     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1109
1110     long mLastWriteTime = 0;
1111
1112     /**
1113      * Used to retain an update lock when the foreground activity is in
1114      * immersive mode.
1115      */
1116     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1117
1118     /**
1119      * Set to true after the system has finished booting.
1120      */
1121     boolean mBooted = false;
1122
1123     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1124     int mProcessLimitOverride = -1;
1125
1126     WindowManagerService mWindowManager;
1127
1128     final ActivityThread mSystemThread;
1129
1130     // Holds the current foreground user's id
1131     int mCurrentUserId = 0;
1132     // Holds the target user's id during a user switch
1133     int mTargetUserId = UserHandle.USER_NULL;
1134     // If there are multiple profiles for the current user, their ids are here
1135     // Currently only the primary user can have managed profiles
1136     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1137
1138     /**
1139      * Mapping from each known user ID to the profile group ID it is associated with.
1140      */
1141     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1142
1143     private UserManagerService mUserManager;
1144
1145     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1146         final ProcessRecord mApp;
1147         final int mPid;
1148         final IApplicationThread mAppThread;
1149
1150         AppDeathRecipient(ProcessRecord app, int pid,
1151                 IApplicationThread thread) {
1152             if (localLOGV) Slog.v(
1153                 TAG, "New death recipient " + this
1154                 + " for thread " + thread.asBinder());
1155             mApp = app;
1156             mPid = pid;
1157             mAppThread = thread;
1158         }
1159
1160         @Override
1161         public void binderDied() {
1162             if (localLOGV) Slog.v(
1163                 TAG, "Death received in " + this
1164                 + " for thread " + mAppThread.asBinder());
1165             synchronized(ActivityManagerService.this) {
1166                 appDiedLocked(mApp, mPid, mAppThread);
1167             }
1168         }
1169     }
1170
1171     static final int SHOW_ERROR_MSG = 1;
1172     static final int SHOW_NOT_RESPONDING_MSG = 2;
1173     static final int SHOW_FACTORY_ERROR_MSG = 3;
1174     static final int UPDATE_CONFIGURATION_MSG = 4;
1175     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1176     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1177     static final int SERVICE_TIMEOUT_MSG = 12;
1178     static final int UPDATE_TIME_ZONE = 13;
1179     static final int SHOW_UID_ERROR_MSG = 14;
1180     static final int IM_FEELING_LUCKY_MSG = 15;
1181     static final int PROC_START_TIMEOUT_MSG = 20;
1182     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1183     static final int KILL_APPLICATION_MSG = 22;
1184     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1185     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1186     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1187     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1188     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1189     static final int CLEAR_DNS_CACHE_MSG = 28;
1190     static final int UPDATE_HTTP_PROXY_MSG = 29;
1191     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1192     static final int DISPATCH_PROCESSES_CHANGED = 31;
1193     static final int DISPATCH_PROCESS_DIED = 32;
1194     static final int REPORT_MEM_USAGE_MSG = 33;
1195     static final int REPORT_USER_SWITCH_MSG = 34;
1196     static final int CONTINUE_USER_SWITCH_MSG = 35;
1197     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1198     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1199     static final int PERSIST_URI_GRANTS_MSG = 38;
1200     static final int REQUEST_ALL_PSS_MSG = 39;
1201     static final int START_PROFILES_MSG = 40;
1202     static final int UPDATE_TIME = 41;
1203     static final int SYSTEM_USER_START_MSG = 42;
1204     static final int SYSTEM_USER_CURRENT_MSG = 43;
1205     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1206     static final int FINISH_BOOTING_MSG = 45;
1207     static final int START_USER_SWITCH_MSG = 46;
1208     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1209
1210     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1211     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1212     static final int FIRST_COMPAT_MODE_MSG = 300;
1213     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1214
1215     AlertDialog mUidAlert;
1216     CompatModeDialog mCompatModeDialog;
1217     long mLastMemUsageReportTime = 0;
1218
1219     private LockToAppRequestDialog mLockToAppRequest;
1220
1221     /**
1222      * Flag whether the current user is a "monkey", i.e. whether
1223      * the UI is driven by a UI automation tool.
1224      */
1225     private boolean mUserIsMonkey;
1226
1227     /** Flag whether the device has a Recents UI */
1228     boolean mHasRecents;
1229
1230     /** The dimensions of the thumbnails in the Recents UI. */
1231     int mThumbnailWidth;
1232     int mThumbnailHeight;
1233
1234     final ServiceThread mHandlerThread;
1235     final MainHandler mHandler;
1236
1237     final class MainHandler extends Handler {
1238         public MainHandler(Looper looper) {
1239             super(looper, null, true);
1240         }
1241
1242         @Override
1243         public void handleMessage(Message msg) {
1244             switch (msg.what) {
1245             case SHOW_ERROR_MSG: {
1246                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1247                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1248                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1249                 synchronized (ActivityManagerService.this) {
1250                     ProcessRecord proc = (ProcessRecord)data.get("app");
1251                     AppErrorResult res = (AppErrorResult) data.get("result");
1252                     if (proc != null && proc.crashDialog != null) {
1253                         Slog.e(TAG, "App already has crash dialog: " + proc);
1254                         if (res != null) {
1255                             res.set(0);
1256                         }
1257                         return;
1258                     }
1259                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1260                             >= Process.FIRST_APPLICATION_UID
1261                             && proc.pid != MY_PID);
1262                     for (int userId : mCurrentProfileIds) {
1263                         isBackground &= (proc.userId != userId);
1264                     }
1265                     if (isBackground && !showBackground) {
1266                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1267                         if (res != null) {
1268                             res.set(0);
1269                         }
1270                         return;
1271                     }
1272                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1273                         Dialog d = new AppErrorDialog(mContext,
1274                                 ActivityManagerService.this, res, proc);
1275                         d.show();
1276                         proc.crashDialog = d;
1277                     } else {
1278                         // The device is asleep, so just pretend that the user
1279                         // saw a crash dialog and hit "force quit".
1280                         if (res != null) {
1281                             res.set(0);
1282                         }
1283                     }
1284                 }
1285
1286                 ensureBootCompleted();
1287             } break;
1288             case SHOW_NOT_RESPONDING_MSG: {
1289                 synchronized (ActivityManagerService.this) {
1290                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1291                     ProcessRecord proc = (ProcessRecord)data.get("app");
1292                     if (proc != null && proc.anrDialog != null) {
1293                         Slog.e(TAG, "App already has anr dialog: " + proc);
1294                         return;
1295                     }
1296
1297                     Intent intent = new Intent("android.intent.action.ANR");
1298                     if (!mProcessesReady) {
1299                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1300                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1301                     }
1302                     broadcastIntentLocked(null, null, intent,
1303                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1304                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1305
1306                     if (mShowDialogs) {
1307                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1308                                 mContext, proc, (ActivityRecord)data.get("activity"),
1309                                 msg.arg1 != 0);
1310                         d.show();
1311                         proc.anrDialog = d;
1312                     } else {
1313                         // Just kill the app if there is no dialog to be shown.
1314                         killAppAtUsersRequest(proc, null);
1315                     }
1316                 }
1317
1318                 ensureBootCompleted();
1319             } break;
1320             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1321                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1322                 synchronized (ActivityManagerService.this) {
1323                     ProcessRecord proc = (ProcessRecord) data.get("app");
1324                     if (proc == null) {
1325                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1326                         break;
1327                     }
1328                     if (proc.crashDialog != null) {
1329                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1330                         return;
1331                     }
1332                     AppErrorResult res = (AppErrorResult) data.get("result");
1333                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334                         Dialog d = new StrictModeViolationDialog(mContext,
1335                                 ActivityManagerService.this, res, proc);
1336                         d.show();
1337                         proc.crashDialog = d;
1338                     } else {
1339                         // The device is asleep, so just pretend that the user
1340                         // saw a crash dialog and hit "force quit".
1341                         res.set(0);
1342                     }
1343                 }
1344                 ensureBootCompleted();
1345             } break;
1346             case SHOW_FACTORY_ERROR_MSG: {
1347                 Dialog d = new FactoryErrorDialog(
1348                     mContext, msg.getData().getCharSequence("msg"));
1349                 d.show();
1350                 ensureBootCompleted();
1351             } break;
1352             case UPDATE_CONFIGURATION_MSG: {
1353                 final ContentResolver resolver = mContext.getContentResolver();
1354                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1355             } break;
1356             case GC_BACKGROUND_PROCESSES_MSG: {
1357                 synchronized (ActivityManagerService.this) {
1358                     performAppGcsIfAppropriateLocked();
1359                 }
1360             } break;
1361             case WAIT_FOR_DEBUGGER_MSG: {
1362                 synchronized (ActivityManagerService.this) {
1363                     ProcessRecord app = (ProcessRecord)msg.obj;
1364                     if (msg.arg1 != 0) {
1365                         if (!app.waitedForDebugger) {
1366                             Dialog d = new AppWaitingForDebuggerDialog(
1367                                     ActivityManagerService.this,
1368                                     mContext, app);
1369                             app.waitDialog = d;
1370                             app.waitedForDebugger = true;
1371                             d.show();
1372                         }
1373                     } else {
1374                         if (app.waitDialog != null) {
1375                             app.waitDialog.dismiss();
1376                             app.waitDialog = null;
1377                         }
1378                     }
1379                 }
1380             } break;
1381             case SERVICE_TIMEOUT_MSG: {
1382                 if (mDidDexOpt) {
1383                     mDidDexOpt = false;
1384                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1385                     nmsg.obj = msg.obj;
1386                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1387                     return;
1388                 }
1389                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1390             } break;
1391             case UPDATE_TIME_ZONE: {
1392                 synchronized (ActivityManagerService.this) {
1393                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1394                         ProcessRecord r = mLruProcesses.get(i);
1395                         if (r.thread != null) {
1396                             try {
1397                                 r.thread.updateTimeZone();
1398                             } catch (RemoteException ex) {
1399                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1400                             }
1401                         }
1402                     }
1403                 }
1404             } break;
1405             case CLEAR_DNS_CACHE_MSG: {
1406                 synchronized (ActivityManagerService.this) {
1407                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1408                         ProcessRecord r = mLruProcesses.get(i);
1409                         if (r.thread != null) {
1410                             try {
1411                                 r.thread.clearDnsCache();
1412                             } catch (RemoteException ex) {
1413                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1414                             }
1415                         }
1416                     }
1417                 }
1418             } break;
1419             case UPDATE_HTTP_PROXY_MSG: {
1420                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1421                 String host = "";
1422                 String port = "";
1423                 String exclList = "";
1424                 Uri pacFileUrl = Uri.EMPTY;
1425                 if (proxy != null) {
1426                     host = proxy.getHost();
1427                     port = Integer.toString(proxy.getPort());
1428                     exclList = proxy.getExclusionListAsString();
1429                     pacFileUrl = proxy.getPacFileUrl();
1430                 }
1431                 synchronized (ActivityManagerService.this) {
1432                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1433                         ProcessRecord r = mLruProcesses.get(i);
1434                         if (r.thread != null) {
1435                             try {
1436                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1437                             } catch (RemoteException ex) {
1438                                 Slog.w(TAG, "Failed to update http proxy for: " +
1439                                         r.info.processName);
1440                             }
1441                         }
1442                     }
1443                 }
1444             } break;
1445             case SHOW_UID_ERROR_MSG: {
1446                 String title = "System UIDs Inconsistent";
1447                 String text = "UIDs on the system are inconsistent, you need to wipe your"
1448                         + " data partition or your device will be unstable.";
1449                 Log.e(TAG, title + ": " + text);
1450                 if (mShowDialogs) {
1451                     // XXX This is a temporary dialog, no need to localize.
1452                     AlertDialog d = new BaseErrorDialog(mContext);
1453                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1454                     d.setCancelable(false);
1455                     d.setTitle(title);
1456                     d.setMessage(text);
1457                     d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1458                             mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1459                     mUidAlert = d;
1460                     d.show();
1461                 }
1462             } break;
1463             case IM_FEELING_LUCKY_MSG: {
1464                 if (mUidAlert != null) {
1465                     mUidAlert.dismiss();
1466                     mUidAlert = null;
1467                 }
1468             } break;
1469             case PROC_START_TIMEOUT_MSG: {
1470                 if (mDidDexOpt) {
1471                     mDidDexOpt = false;
1472                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1473                     nmsg.obj = msg.obj;
1474                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1475                     return;
1476                 }
1477                 ProcessRecord app = (ProcessRecord)msg.obj;
1478                 synchronized (ActivityManagerService.this) {
1479                     processStartTimedOutLocked(app);
1480                 }
1481             } break;
1482             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1483                 synchronized (ActivityManagerService.this) {
1484                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1485                 }
1486             } break;
1487             case KILL_APPLICATION_MSG: {
1488                 synchronized (ActivityManagerService.this) {
1489                     int appid = msg.arg1;
1490                     boolean restart = (msg.arg2 == 1);
1491                     Bundle bundle = (Bundle)msg.obj;
1492                     String pkg = bundle.getString("pkg");
1493                     String reason = bundle.getString("reason");
1494                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1495                             false, UserHandle.USER_ALL, reason);
1496                 }
1497             } break;
1498             case FINALIZE_PENDING_INTENT_MSG: {
1499                 ((PendingIntentRecord)msg.obj).completeFinalize();
1500             } break;
1501             case POST_HEAVY_NOTIFICATION_MSG: {
1502                 INotificationManager inm = NotificationManager.getService();
1503                 if (inm == null) {
1504                     return;
1505                 }
1506
1507                 ActivityRecord root = (ActivityRecord)msg.obj;
1508                 ProcessRecord process = root.app;
1509                 if (process == null) {
1510                     return;
1511                 }
1512
1513                 try {
1514                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1515                     String text = mContext.getString(R.string.heavy_weight_notification,
1516                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1517                     Notification notification = new Notification();
1518                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1519                     notification.when = 0;
1520                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1521                     notification.tickerText = text;
1522                     notification.defaults = 0; // please be quiet
1523                     notification.sound = null;
1524                     notification.vibrate = null;
1525                     notification.color = mContext.getResources().getColor(
1526                             com.android.internal.R.color.system_notification_accent_color);
1527                     notification.setLatestEventInfo(context, text,
1528                             mContext.getText(R.string.heavy_weight_notification_detail),
1529                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1530                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1531                                     new UserHandle(root.userId)));
1532
1533                     try {
1534                         int[] outId = new int[1];
1535                         inm.enqueueNotificationWithTag("android", "android", null,
1536                                 R.string.heavy_weight_notification,
1537                                 notification, outId, root.userId);
1538                     } catch (RuntimeException e) {
1539                         Slog.w(ActivityManagerService.TAG,
1540                                 "Error showing notification for heavy-weight app", e);
1541                     } catch (RemoteException e) {
1542                     }
1543                 } catch (NameNotFoundException e) {
1544                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1545                 }
1546             } break;
1547             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1548                 INotificationManager inm = NotificationManager.getService();
1549                 if (inm == null) {
1550                     return;
1551                 }
1552                 try {
1553                     inm.cancelNotificationWithTag("android", null,
1554                             R.string.heavy_weight_notification,  msg.arg1);
1555                 } catch (RuntimeException e) {
1556                     Slog.w(ActivityManagerService.TAG,
1557                             "Error canceling notification for service", e);
1558                 } catch (RemoteException e) {
1559                 }
1560             } break;
1561             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1562                 synchronized (ActivityManagerService.this) {
1563                     checkExcessivePowerUsageLocked(true);
1564                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1565                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1566                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1567                 }
1568             } break;
1569             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1570                 synchronized (ActivityManagerService.this) {
1571                     ActivityRecord ar = (ActivityRecord)msg.obj;
1572                     if (mCompatModeDialog != null) {
1573                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1574                                 ar.info.applicationInfo.packageName)) {
1575                             return;
1576                         }
1577                         mCompatModeDialog.dismiss();
1578                         mCompatModeDialog = null;
1579                     }
1580                     if (ar != null && false) {
1581                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1582                                 ar.packageName)) {
1583                             int mode = mCompatModePackages.computeCompatModeLocked(
1584                                     ar.info.applicationInfo);
1585                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1586                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1587                                 mCompatModeDialog = new CompatModeDialog(
1588                                         ActivityManagerService.this, mContext,
1589                                         ar.info.applicationInfo);
1590                                 mCompatModeDialog.show();
1591                             }
1592                         }
1593                     }
1594                 }
1595                 break;
1596             }
1597             case DISPATCH_PROCESSES_CHANGED: {
1598                 dispatchProcessesChanged();
1599                 break;
1600             }
1601             case DISPATCH_PROCESS_DIED: {
1602                 final int pid = msg.arg1;
1603                 final int uid = msg.arg2;
1604                 dispatchProcessDied(pid, uid);
1605                 break;
1606             }
1607             case REPORT_MEM_USAGE_MSG: {
1608                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1609                 Thread thread = new Thread() {
1610                     @Override public void run() {
1611                         final SparseArray<ProcessMemInfo> infoMap
1612                                 = new SparseArray<ProcessMemInfo>(memInfos.size());
1613                         for (int i=0, N=memInfos.size(); i<N; i++) {
1614                             ProcessMemInfo mi = memInfos.get(i);
1615                             infoMap.put(mi.pid, mi);
1616                         }
1617                         updateCpuStatsNow();
1618                         synchronized (mProcessCpuTracker) {
1619                             final int N = mProcessCpuTracker.countStats();
1620                             for (int i=0; i<N; i++) {
1621                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1622                                 if (st.vsize > 0) {
1623                                     long pss = Debug.getPss(st.pid, null);
1624                                     if (pss > 0) {
1625                                         if (infoMap.indexOfKey(st.pid) < 0) {
1626                                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1627                                                     ProcessList.NATIVE_ADJ, -1, "native", null);
1628                                             mi.pss = pss;
1629                                             memInfos.add(mi);
1630                                         }
1631                                     }
1632                                 }
1633                             }
1634                         }
1635
1636                         long totalPss = 0;
1637                         for (int i=0, N=memInfos.size(); i<N; i++) {
1638                             ProcessMemInfo mi = memInfos.get(i);
1639                             if (mi.pss == 0) {
1640                                 mi.pss = Debug.getPss(mi.pid, null);
1641                             }
1642                             totalPss += mi.pss;
1643                         }
1644                         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1645                             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1646                                 if (lhs.oomAdj != rhs.oomAdj) {
1647                                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1648                                 }
1649                                 if (lhs.pss != rhs.pss) {
1650                                     return lhs.pss < rhs.pss ? 1 : -1;
1651                                 }
1652                                 return 0;
1653                             }
1654                         });
1655
1656                         StringBuilder tag = new StringBuilder(128);
1657                         StringBuilder stack = new StringBuilder(128);
1658                         tag.append("Low on memory -- ");
1659                         appendMemBucket(tag, totalPss, "total", false);
1660                         appendMemBucket(stack, totalPss, "total", true);
1661
1662                         StringBuilder logBuilder = new StringBuilder(1024);
1663                         logBuilder.append("Low on memory:\n");
1664
1665                         boolean firstLine = true;
1666                         int lastOomAdj = Integer.MIN_VALUE;
1667                         for (int i=0, N=memInfos.size(); i<N; i++) {
1668                             ProcessMemInfo mi = memInfos.get(i);
1669
1670                             if (mi.oomAdj != ProcessList.NATIVE_ADJ
1671                                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
1672                                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
1673                                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1674                                 if (lastOomAdj != mi.oomAdj) {
1675                                     lastOomAdj = mi.oomAdj;
1676                                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1677                                         tag.append(" / ");
1678                                     }
1679                                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1680                                         if (firstLine) {
1681                                             stack.append(":");
1682                                             firstLine = false;
1683                                         }
1684                                         stack.append("\n\t at ");
1685                                     } else {
1686                                         stack.append("$");
1687                                     }
1688                                 } else {
1689                                     tag.append(" ");
1690                                     stack.append("$");
1691                                 }
1692                                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1693                                     appendMemBucket(tag, mi.pss, mi.name, false);
1694                                 }
1695                                 appendMemBucket(stack, mi.pss, mi.name, true);
1696                                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1697                                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1698                                     stack.append("(");
1699                                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1700                                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1701                                             stack.append(DUMP_MEM_OOM_LABEL[k]);
1702                                             stack.append(":");
1703                                             stack.append(DUMP_MEM_OOM_ADJ[k]);
1704                                         }
1705                                     }
1706                                     stack.append(")");
1707                                 }
1708                             }
1709
1710                             logBuilder.append("  ");
1711                             logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1712                             logBuilder.append(' ');
1713                             logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1714                             logBuilder.append(' ');
1715                             ProcessList.appendRamKb(logBuilder, mi.pss);
1716                             logBuilder.append(" kB: ");
1717                             logBuilder.append(mi.name);
1718                             logBuilder.append(" (");
1719                             logBuilder.append(mi.pid);
1720                             logBuilder.append(") ");
1721                             logBuilder.append(mi.adjType);
1722                             logBuilder.append('\n');
1723                             if (mi.adjReason != null) {
1724                                 logBuilder.append("                      ");
1725                                 logBuilder.append(mi.adjReason);
1726                                 logBuilder.append('\n');
1727                             }
1728                         }
1729
1730                         logBuilder.append("           ");
1731                         ProcessList.appendRamKb(logBuilder, totalPss);
1732                         logBuilder.append(" kB: TOTAL\n");
1733
1734                         long[] infos = new long[Debug.MEMINFO_COUNT];
1735                         Debug.getMemInfo(infos);
1736                         logBuilder.append("  MemInfo: ");
1737                         logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1738                         logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1739                         logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1740                         logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1741                         logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1742                         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1743                             logBuilder.append("  ZRAM: ");
1744                             logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1745                             logBuilder.append(" kB RAM, ");
1746                             logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1747                             logBuilder.append(" kB swap total, ");
1748                             logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1749                             logBuilder.append(" kB swap free\n");
1750                         }
1751                         Slog.i(TAG, logBuilder.toString());
1752
1753                         StringBuilder dropBuilder = new StringBuilder(1024);
1754                         /*
1755                         StringWriter oomSw = new StringWriter();
1756                         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1757                         StringWriter catSw = new StringWriter();
1758                         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1759                         String[] emptyArgs = new String[] { };
1760                         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1761                         oomPw.flush();
1762                         String oomString = oomSw.toString();
1763                         */
1764                         dropBuilder.append(stack);
1765                         dropBuilder.append('\n');
1766                         dropBuilder.append('\n');
1767                         dropBuilder.append(logBuilder);
1768                         dropBuilder.append('\n');
1769                         /*
1770                         dropBuilder.append(oomString);
1771                         dropBuilder.append('\n');
1772                         */
1773                         StringWriter catSw = new StringWriter();
1774                         synchronized (ActivityManagerService.this) {
1775                             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1776                             String[] emptyArgs = new String[] { };
1777                             catPw.println();
1778                             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1779                             catPw.println();
1780                             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1781                                     false, false, null);
1782                             catPw.println();
1783                             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1784                             catPw.flush();
1785                         }
1786                         dropBuilder.append(catSw.toString());
1787                         addErrorToDropBox("lowmem", null, "system_server", null,
1788                                 null, tag.toString(), dropBuilder.toString(), null, null);
1789                         //Slog.i(TAG, "Sent to dropbox:");
1790                         //Slog.i(TAG, dropBuilder.toString());
1791                         synchronized (ActivityManagerService.this) {
1792                             long now = SystemClock.uptimeMillis();
1793                             if (mLastMemUsageReportTime < now) {
1794                                 mLastMemUsageReportTime = now;
1795                             }
1796                         }
1797                     }
1798                 };
1799                 thread.start();
1800                 break;
1801             }
1802             case START_USER_SWITCH_MSG: {
1803                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1804                 break;
1805             }
1806             case REPORT_USER_SWITCH_MSG: {
1807                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1808                 break;
1809             }
1810             case CONTINUE_USER_SWITCH_MSG: {
1811                 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1812                 break;
1813             }
1814             case USER_SWITCH_TIMEOUT_MSG: {
1815                 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1816                 break;
1817             }
1818             case IMMERSIVE_MODE_LOCK_MSG: {
1819                 final boolean nextState = (msg.arg1 != 0);
1820                 if (mUpdateLock.isHeld() != nextState) {
1821                     if (DEBUG_IMMERSIVE) {
1822                         final ActivityRecord r = (ActivityRecord) msg.obj;
1823                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1824                     }
1825                     if (nextState) {
1826                         mUpdateLock.acquire();
1827                     } else {
1828                         mUpdateLock.release();
1829                     }
1830                 }
1831                 break;
1832             }
1833             case PERSIST_URI_GRANTS_MSG: {
1834                 writeGrantedUriPermissions();
1835                 break;
1836             }
1837             case REQUEST_ALL_PSS_MSG: {
1838                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1839                 break;
1840             }
1841             case START_PROFILES_MSG: {
1842                 synchronized (ActivityManagerService.this) {
1843                     startProfilesLocked();
1844                 }
1845                 break;
1846             }
1847             case UPDATE_TIME: {
1848                 synchronized (ActivityManagerService.this) {
1849                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1850                         ProcessRecord r = mLruProcesses.get(i);
1851                         if (r.thread != null) {
1852                             try {
1853                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1854                             } catch (RemoteException ex) {
1855                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1856                             }
1857                         }
1858                     }
1859                 }
1860                 break;
1861             }
1862             case SYSTEM_USER_START_MSG: {
1863                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1864                         Integer.toString(msg.arg1), msg.arg1);
1865                 mSystemServiceManager.startUser(msg.arg1);
1866                 break;
1867             }
1868             case SYSTEM_USER_CURRENT_MSG: {
1869                 mBatteryStatsService.noteEvent(
1870                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1871                         Integer.toString(msg.arg2), msg.arg2);
1872                 mBatteryStatsService.noteEvent(
1873                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1874                         Integer.toString(msg.arg1), msg.arg1);
1875                 mSystemServiceManager.switchUser(msg.arg1);
1876                 mLockToAppRequest.clearPrompt();
1877                 break;
1878             }
1879             case ENTER_ANIMATION_COMPLETE_MSG: {
1880                 synchronized (ActivityManagerService.this) {
1881                     ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1882                     if (r != null && r.app != null && r.app.thread != null) {
1883                         try {
1884                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1885                         } catch (RemoteException e) {
1886                         }
1887                     }
1888                 }
1889                 break;
1890             }
1891             case FINISH_BOOTING_MSG: {
1892                 if (msg.arg1 != 0) {
1893                     finishBooting();
1894                 }
1895                 if (msg.arg2 != 0) {
1896                     enableScreenAfterBoot();
1897                 }
1898                 break;
1899             }
1900             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1901                 try {
1902                     Locale l = (Locale) msg.obj;
1903                     IBinder service = ServiceManager.getService("mount");
1904                     IMountService mountService = IMountService.Stub.asInterface(service);
1905                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1906                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1907                 } catch (RemoteException e) {
1908                     Log.e(TAG, "Error storing locale for decryption UI", e);
1909                 }
1910                 break;
1911             }
1912             }
1913         }
1914     };
1915
1916     static final int COLLECT_PSS_BG_MSG = 1;
1917
1918     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1919         @Override
1920         public void handleMessage(Message msg) {
1921             switch (msg.what) {
1922             case COLLECT_PSS_BG_MSG: {
1923                 long start = SystemClock.uptimeMillis();
1924                 MemInfoReader memInfo = null;
1925                 synchronized (ActivityManagerService.this) {
1926                     if (mFullPssPending) {
1927                         mFullPssPending = false;
1928                         memInfo = new MemInfoReader();
1929                     }
1930                 }
1931                 if (memInfo != null) {
1932                     updateCpuStatsNow();
1933                     long nativeTotalPss = 0;
1934                     synchronized (mProcessCpuTracker) {
1935                         final int N = mProcessCpuTracker.countStats();
1936                         for (int j=0; j<N; j++) {
1937                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1938                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1939                                 // This is definitely an application process; skip it.
1940                                 continue;
1941                             }
1942                             synchronized (mPidsSelfLocked) {
1943                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1944                                     // This is one of our own processes; skip it.
1945                                     continue;
1946                                 }
1947                             }
1948                             nativeTotalPss += Debug.getPss(st.pid, null);
1949                         }
1950                     }
1951                     memInfo.readMemInfo();
1952                     synchronized (ActivityManagerService.this) {
1953                         if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1954                                 + (SystemClock.uptimeMillis()-start) + "ms");
1955                         mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1956                                 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1957                                 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1958                                         +memInfo.getSlabSizeKb(),
1959                                 nativeTotalPss);
1960                     }
1961                 }
1962
1963                 int i=0, num=0;
1964                 long[] tmp = new long[1];
1965                 do {
1966                     ProcessRecord proc;
1967                     int procState;
1968                     int pid;
1969                     synchronized (ActivityManagerService.this) {
1970                         if (i >= mPendingPssProcesses.size()) {
1971                             if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1972                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1973                             mPendingPssProcesses.clear();
1974                             return;
1975                         }
1976                         proc = mPendingPssProcesses.get(i);
1977                         procState = proc.pssProcState;
1978                         if (proc.thread != null && procState == proc.setProcState) {
1979                             pid = proc.pid;
1980                         } else {
1981                             proc = null;
1982                             pid = 0;
1983                         }
1984                         i++;
1985                     }
1986                     if (proc != null) {
1987                         long pss = Debug.getPss(pid, tmp);
1988                         synchronized (ActivityManagerService.this) {
1989                             if (proc.thread != null && proc.setProcState == procState
1990                                     && proc.pid == pid) {
1991                                 num++;
1992                                 proc.lastPssTime = SystemClock.uptimeMillis();
1993                                 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1994                                 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1995                                         + ": " + pss + " lastPss=" + proc.lastPss
1996                                         + " state=" + ProcessList.makeProcStateString(procState));
1997                                 if (proc.initialIdlePss == 0) {
1998                                     proc.initialIdlePss = pss;
1999                                 }
2000                                 proc.lastPss = pss;
2001                                 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2002                                     proc.lastCachedPss = pss;
2003                                 }
2004                             }
2005                         }
2006                     }
2007                 } while (true);
2008             }
2009             }
2010         }
2011     };
2012
2013     /**
2014      * Monitor for package changes and update our internal state.
2015      */
2016     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2017         @Override
2018         public void onPackageRemoved(String packageName, int uid) {
2019             // Remove all tasks with activities in the specified package from the list of recent tasks
2020             final int eventUserId = getChangingUserId();
2021             synchronized (ActivityManagerService.this) {
2022                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2023                     TaskRecord tr = mRecentTasks.get(i);
2024                     if (tr.userId != eventUserId) continue;
2025
2026                     ComponentName cn = tr.intent.getComponent();
2027                     if (cn != null && cn.getPackageName().equals(packageName)) {
2028                         // If the package name matches, remove the task and kill the process
2029                         removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2030                     }
2031                 }
2032             }
2033         }
2034
2035         @Override
2036         public boolean onPackageChanged(String packageName, int uid, String[] components) {
2037             onPackageModified(packageName);
2038             return true;
2039         }
2040
2041         @Override
2042         public void onPackageModified(String packageName) {
2043             final int eventUserId = getChangingUserId();
2044             final IPackageManager pm = AppGlobals.getPackageManager();
2045             final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2046                     new ArrayList<Pair<Intent, Integer>>();
2047             final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2048             final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2049             // Copy the list of recent tasks so that we don't hold onto the lock on
2050             // ActivityManagerService for long periods while checking if components exist.
2051             synchronized (ActivityManagerService.this) {
2052                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2053                     TaskRecord tr = mRecentTasks.get(i);
2054                     if (tr.userId != eventUserId) continue;
2055
2056                     recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2057                 }
2058             }
2059             // Check the recent tasks and filter out all tasks with components that no longer exist.
2060             for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2061                 Pair<Intent, Integer> p = recentTaskIntents.get(i);
2062                 ComponentName cn = p.first.getComponent();
2063                 if (cn != null && cn.getPackageName().equals(packageName)) {
2064                     if (componentsKnownToExist.contains(cn)) {
2065                         // If we know that the component still exists in the package, then skip
2066                         continue;
2067                     }
2068                     try {
2069                         ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2070                         if (info != null) {
2071                             componentsKnownToExist.add(cn);
2072                         } else {
2073                             tasksToRemove.add(p.second);
2074                         }
2075                     } catch (RemoteException e) {
2076                         Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2077                     }
2078                 }
2079             }
2080             // Prune all the tasks with removed components from the list of recent tasks
2081             synchronized (ActivityManagerService.this) {
2082                 for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2083                     // Remove the task but don't kill the process (since other components in that
2084                     // package may still be running and in the background)
2085                     removeTaskByIdLocked(tasksToRemove.get(i), 0);
2086                 }
2087             }
2088         }
2089
2090         @Override
2091         public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2092             // Force stop the specified packages
2093             int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2094             if (packages != null) {
2095                 for (String pkg : packages) {
2096                     synchronized (ActivityManagerService.this) {
2097                         if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2098                                 userId, "finished booting")) {
2099                             return true;
2100                         }
2101                     }
2102                 }
2103             }
2104             return false;
2105         }
2106     };
2107
2108     public void setSystemProcess() {
2109         try {
2110             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2111             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2112             ServiceManager.addService("meminfo", new MemBinder(this));
2113             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2114             ServiceManager.addService("dbinfo", new DbBinder(this));
2115             if (MONITOR_CPU_USAGE) {
2116                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2117             }
2118             ServiceManager.addService("permission", new PermissionController(this));
2119
2120             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2121                     "android", STOCK_PM_FLAGS);
2122             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2123
2124             synchronized (this) {
2125                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2126                 app.persistent = true;
2127                 app.pid = MY_PID;
2128                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2129                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2130                 mProcessNames.put(app.processName, app.uid, app);
2131                 synchronized (mPidsSelfLocked) {
2132                     mPidsSelfLocked.put(app.pid, app);
2133                 }
2134                 updateLruProcessLocked(app, false, null);
2135                 updateOomAdjLocked();
2136             }
2137         } catch (PackageManager.NameNotFoundException e) {
2138             throw new RuntimeException(
2139                     "Unable to find android system package", e);
2140         }
2141     }
2142
2143     public void setWindowManager(WindowManagerService wm) {
2144         mWindowManager = wm;
2145         mStackSupervisor.setWindowManager(wm);
2146     }
2147
2148     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2149         mUsageStatsService = usageStatsManager;
2150     }
2151
2152     public void startObservingNativeCrashes() {
2153         final NativeCrashListener ncl = new NativeCrashListener(this);
2154         ncl.start();
2155     }
2156
2157     public IAppOpsService getAppOpsService() {
2158         return mAppOpsService;
2159     }
2160
2161     static class MemBinder extends Binder {
2162         ActivityManagerService mActivityManagerService;
2163         MemBinder(ActivityManagerService activityManagerService) {
2164             mActivityManagerService = activityManagerService;
2165         }
2166
2167         @Override
2168         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2169             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2170                     != PackageManager.PERMISSION_GRANTED) {
2171                 pw.println("Permission Denial: can't dump meminfo from from pid="
2172                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2173                         + " without permission " + android.Manifest.permission.DUMP);
2174                 return;
2175             }
2176
2177             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2178         }
2179     }
2180
2181     static class GraphicsBinder extends Binder {
2182         ActivityManagerService mActivityManagerService;
2183         GraphicsBinder(ActivityManagerService activityManagerService) {
2184             mActivityManagerService = activityManagerService;
2185         }
2186
2187         @Override
2188         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2189             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2190                     != PackageManager.PERMISSION_GRANTED) {
2191                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2192                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2193                         + " without permission " + android.Manifest.permission.DUMP);
2194                 return;
2195             }
2196
2197             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2198         }
2199     }
2200
2201     static class DbBinder extends Binder {
2202         ActivityManagerService mActivityManagerService;
2203         DbBinder(ActivityManagerService activityManagerService) {
2204             mActivityManagerService = activityManagerService;
2205         }
2206
2207         @Override
2208         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2209             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2210                     != PackageManager.PERMISSION_GRANTED) {
2211                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2212                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2213                         + " without permission " + android.Manifest.permission.DUMP);
2214                 return;
2215             }
2216
2217             mActivityManagerService.dumpDbInfo(fd, pw, args);
2218         }
2219     }
2220
2221     static class CpuBinder extends Binder {
2222         ActivityManagerService mActivityManagerService;
2223         CpuBinder(ActivityManagerService activityManagerService) {
2224             mActivityManagerService = activityManagerService;
2225         }
2226
2227         @Override
2228         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2229             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2230                     != PackageManager.PERMISSION_GRANTED) {
2231                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2232                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2233                         + " without permission " + android.Manifest.permission.DUMP);
2234                 return;
2235             }
2236
2237             synchronized (mActivityManagerService.mProcessCpuTracker) {
2238                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2239                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2240                         SystemClock.uptimeMillis()));
2241             }
2242         }
2243     }
2244
2245     public static final class Lifecycle extends SystemService {
2246         private final ActivityManagerService mService;
2247
2248         public Lifecycle(Context context) {
2249             super(context);
2250             mService = new ActivityManagerService(context);
2251         }
2252
2253         @Override
2254         public void onStart() {
2255             mService.start();
2256         }
2257
2258         public ActivityManagerService getService() {
2259             return mService;
2260         }
2261     }
2262
2263     // Note: This method is invoked on the main thread but may need to attach various
2264     // handlers to other threads.  So take care to be explicit about the looper.
2265     public ActivityManagerService(Context systemContext) {
2266         mContext = systemContext;
2267         mFactoryTest = FactoryTest.getMode();
2268         mSystemThread = ActivityThread.currentActivityThread();
2269
2270         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2271
2272         mHandlerThread = new ServiceThread(TAG,
2273                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2274         mHandlerThread.start();
2275         mHandler = new MainHandler(mHandlerThread.getLooper());
2276
2277         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278                 "foreground", BROADCAST_FG_TIMEOUT, false);
2279         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2280                 "background", BROADCAST_BG_TIMEOUT, true);
2281         mBroadcastQueues[0] = mFgBroadcastQueue;
2282         mBroadcastQueues[1] = mBgBroadcastQueue;
2283
2284         mServices = new ActiveServices(this);
2285         mProviderMap = new ProviderMap(this);
2286
2287         // TODO: Move creation of battery stats service outside of activity manager service.
2288         File dataDir = Environment.getDataDirectory();
2289         File systemDir = new File(dataDir, "system");
2290         systemDir.mkdirs();
2291         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2292         mBatteryStatsService.getActiveStatistics().readLocked();
2293         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2294         mOnBattery = DEBUG_POWER ? true
2295                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2296         mBatteryStatsService.getActiveStatistics().setCallback(this);
2297
2298         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2299
2300         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2301
2302         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2303
2304         // User 0 is the first and only user that runs at boot.
2305         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2306         mUserLru.add(Integer.valueOf(0));
2307         updateStartedUserArrayLocked();
2308
2309         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2310             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2311
2312         mConfiguration.setToDefaults();
2313         mConfiguration.setLocale(Locale.getDefault());
2314
2315         mConfigurationSeq = mConfiguration.seq = 1;
2316         mProcessCpuTracker.init();
2317
2318         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2319         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2320         mStackSupervisor = new ActivityStackSupervisor(this);
2321         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2322
2323         mProcessCpuThread = new Thread("CpuTracker") {
2324             @Override
2325             public void run() {
2326                 while (true) {
2327                     try {
2328                         try {
2329                             synchronized(this) {
2330                                 final long now = SystemClock.uptimeMillis();
2331                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2332                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2333                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2334                                 //        + ", write delay=" + nextWriteDelay);
2335                                 if (nextWriteDelay < nextCpuDelay) {
2336                                     nextCpuDelay = nextWriteDelay;
2337                                 }
2338                                 if (nextCpuDelay > 0) {
2339                                     mProcessCpuMutexFree.set(true);
2340                                     this.wait(nextCpuDelay);
2341                                 }
2342                             }
2343                         } catch (InterruptedException e) {
2344                         }
2345                         updateCpuStatsNow();
2346                     } catch (Exception e) {
2347                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2348                     }
2349                 }
2350             }
2351         };
2352
2353         mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2354
2355         Watchdog.getInstance().addMonitor(this);
2356         Watchdog.getInstance().addThread(mHandler);
2357     }
2358
2359     public void setSystemServiceManager(SystemServiceManager mgr) {
2360         mSystemServiceManager = mgr;
2361     }
2362
2363     private void start() {
2364         Process.removeAllProcessGroups();
2365         mProcessCpuThread.start();
2366
2367         mBatteryStatsService.publish(mContext);
2368         mAppOpsService.publish(mContext);
2369         Slog.d("AppOps", "AppOpsService published");
2370         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2371     }
2372
2373     public void initPowerManagement() {
2374         mStackSupervisor.initPowerManagement();
2375         mBatteryStatsService.initPowerManagement();
2376     }
2377
2378     @Override
2379     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2380             throws RemoteException {
2381         if (code == SYSPROPS_TRANSACTION) {
2382             // We need to tell all apps about the system property change.
2383             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2384             synchronized(this) {
2385                 final int NP = mProcessNames.getMap().size();
2386                 for (int ip=0; ip<NP; ip++) {
2387                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2388                     final int NA = apps.size();
2389                     for (int ia=0; ia<NA; ia++) {
2390                         ProcessRecord app = apps.valueAt(ia);
2391                         if (app.thread != null) {
2392                             procs.add(app.thread.asBinder());
2393                         }
2394                     }
2395                 }
2396             }
2397
2398             int N = procs.size();
2399             for (int i=0; i<N; i++) {
2400                 Parcel data2 = Parcel.obtain();
2401                 try {
2402                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2403                 } catch (RemoteException e) {
2404                 }
2405                 data2.recycle();
2406             }
2407         }
2408         try {
2409             return super.onTransact(code, data, reply, flags);
2410         } catch (RuntimeException e) {
2411             // The activity manager only throws security exceptions, so let's
2412             // log all others.
2413             if (!(e instanceof SecurityException)) {
2414                 Slog.wtf(TAG, "Activity Manager Crash", e);
2415             }
2416             throw e;
2417         }
2418     }
2419
2420     void updateCpuStats() {
2421         final long now = SystemClock.uptimeMillis();
2422         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2423             return;
2424         }
2425         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2426             synchronized (mProcessCpuThread) {
2427                 mProcessCpuThread.notify();
2428             }
2429         }
2430     }
2431
2432     void updateCpuStatsNow() {
2433         synchronized (mProcessCpuTracker) {
2434             mProcessCpuMutexFree.set(false);
2435             final long now = SystemClock.uptimeMillis();
2436             boolean haveNewCpuStats = false;
2437
2438             if (MONITOR_CPU_USAGE &&
2439                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2440                 mLastCpuTime.set(now);
2441                 haveNewCpuStats = true;
2442                 mProcessCpuTracker.update();
2443                 //Slog.i(TAG, mProcessCpu.printCurrentState());
2444                 //Slog.i(TAG, "Total CPU usage: "
2445                 //        + mProcessCpu.getTotalCpuPercent() + "%");
2446
2447                 // Slog the cpu usage if the property is set.
2448                 if ("true".equals(SystemProperties.get("events.cpu"))) {
2449                     int user = mProcessCpuTracker.getLastUserTime();
2450                     int system = mProcessCpuTracker.getLastSystemTime();
2451                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
2452                     int irq = mProcessCpuTracker.getLastIrqTime();
2453                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2454                     int idle = mProcessCpuTracker.getLastIdleTime();
2455
2456                     int total = user + system + iowait + irq + softIrq + idle;
2457                     if (total == 0) total = 1;
2458
2459                     EventLog.writeEvent(EventLogTags.CPU,
2460                             ((user+system+iowait+irq+softIrq) * 100) / total,
2461                             (user * 100) / total,
2462                             (system * 100) / total,
2463                             (iowait * 100) / total,
2464                             (irq * 100) / total,
2465                             (softIrq * 100) / total);
2466                 }
2467             }
2468
2469             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2470             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2471             synchronized(bstats) {
2472                 synchronized(mPidsSelfLocked) {
2473                     if (haveNewCpuStats) {
2474                         if (mOnBattery) {
2475                             int perc = bstats.startAddingCpuLocked();
2476                             int totalUTime = 0;
2477                             int totalSTime = 0;
2478                             final int N = mProcessCpuTracker.countStats();
2479                             for (int i=0; i<N; i++) {
2480                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2481                                 if (!st.working) {
2482                                     continue;
2483                                 }
2484                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2485                                 int otherUTime = (st.rel_utime*perc)/100;
2486                                 int otherSTime = (st.rel_stime*perc)/100;
2487                                 totalUTime += otherUTime;
2488                                 totalSTime += otherSTime;
2489                                 if (pr != null) {
2490                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2491                                     if (ps == null || !ps.isActive()) {
2492                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2493                                                 pr.info.uid, pr.processName);
2494                                     }
2495                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2496                                             st.rel_stime-otherSTime);
2497                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2498                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2499                                 } else {
2500                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2501                                     if (ps == null || !ps.isActive()) {
2502                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2503                                                 bstats.mapUid(st.uid), st.name);
2504                                     }
2505                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2506                                             st.rel_stime-otherSTime);
2507                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2508                                 }
2509                             }
2510                             bstats.finishAddingCpuLocked(perc, totalUTime,
2511                                     totalSTime, cpuSpeedTimes);
2512                         }
2513                     }
2514                 }
2515
2516                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2517                     mLastWriteTime = now;
2518                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2519                 }
2520             }
2521         }
2522     }
2523
2524     @Override
2525     public void batteryNeedsCpuUpdate() {
2526         updateCpuStatsNow();
2527     }
2528
2529     @Override
2530     public void batteryPowerChanged(boolean onBattery) {
2531         // When plugging in, update the CPU stats first before changing
2532         // the plug state.
2533         updateCpuStatsNow();
2534         synchronized (this) {
2535             synchronized(mPidsSelfLocked) {
2536                 mOnBattery = DEBUG_POWER ? true : onBattery;
2537             }
2538         }
2539     }
2540
2541     /**
2542      * Initialize the application bind args. These are passed to each
2543      * process when the bindApplication() IPC is sent to the process. They're
2544      * lazily setup to make sure the services are running when they're asked for.
2545      */
2546     private HashMap<String, IBinder> getCommonServicesLocked() {
2547         if (mAppBindArgs == null) {
2548             mAppBindArgs = new HashMap<String, IBinder>();
2549
2550             // Setup the application init args
2551             mAppBindArgs.put("package", ServiceManager.getService("package"));
2552             mAppBindArgs.put("window", ServiceManager.getService("window"));
2553             mAppBindArgs.put(Context.ALARM_SERVICE,
2554                     ServiceManager.getService(Context.ALARM_SERVICE));
2555         }
2556         return mAppBindArgs;
2557     }
2558
2559     final void setFocusedActivityLocked(ActivityRecord r) {
2560         if (mFocusedActivity != r) {
2561             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2562             mFocusedActivity = r;
2563             if (r.task != null && r.task.voiceInteractor != null) {
2564                 startRunningVoiceLocked();
2565             } else {
2566                 finishRunningVoiceLocked();
2567             }
2568             mStackSupervisor.setFocusedStack(r);
2569             if (r != null) {
2570                 mWindowManager.setFocusedApp(r.appToken, true);
2571             }
2572             applyUpdateLockStateLocked(r);
2573         }
2574     }
2575
2576     final void clearFocusedActivity(ActivityRecord r) {
2577         if (mFocusedActivity == r) {
2578             mFocusedActivity = null;
2579         }
2580     }
2581
2582     @Override
2583     public void setFocusedStack(int stackId) {
2584         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2585         synchronized (ActivityManagerService.this) {
2586             ActivityStack stack = mStackSupervisor.getStack(stackId);
2587             if (stack != null) {
2588                 ActivityRecord r = stack.topRunningActivityLocked(null);
2589                 if (r != null) {
2590                     setFocusedActivityLocked(r);
2591                 }
2592             }
2593         }
2594     }
2595
2596     @Override
2597     public void notifyActivityDrawn(IBinder token) {
2598         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2599         synchronized (this) {
2600             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2601             if (r != null) {
2602                 r.task.stack.notifyActivityDrawnLocked(r);
2603             }
2604         }
2605     }
2606
2607     final void applyUpdateLockStateLocked(ActivityRecord r) {
2608         // Modifications to the UpdateLock state are done on our handler, outside
2609         // the activity manager's locks.  The new state is determined based on the
2610         // state *now* of the relevant activity record.  The object is passed to
2611         // the handler solely for logging detail, not to be consulted/modified.
2612         final boolean nextState = r != null && r.immersive;
2613         mHandler.sendMessage(
2614                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2615     }
2616
2617     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2618         Message msg = Message.obtain();
2619         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2620         msg.obj = r.task.askedCompatMode ? null : r;
2621         mHandler.sendMessage(msg);
2622     }
2623
2624     private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2625             String what, Object obj, ProcessRecord srcApp) {
2626         app.lastActivityTime = now;
2627
2628         if (app.activities.size() > 0) {
2629             // Don't want to touch dependent processes that are hosting activities.
2630             return index;
2631         }
2632
2633         int lrui = mLruProcesses.lastIndexOf(app);
2634         if (lrui < 0) {
2635             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2636                     + what + " " + obj + " from " + srcApp);
2637             return index;
2638         }
2639
2640         if (lrui >= index) {
2641             // Don't want to cause this to move dependent processes *back* in the
2642             // list as if they were less frequently used.
2643             return index;
2644         }
2645
2646         if (lrui >= mLruProcessActivityStart) {
2647             // Don't want to touch dependent processes that are hosting activities.
2648             return index;
2649         }
2650
2651         mLruProcesses.remove(lrui);
2652         if (index > 0) {
2653             index--;
2654         }
2655         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2656                 + " in LRU list: " + app);
2657         mLruProcesses.add(index, app);
2658         return index;
2659     }
2660
2661     final void removeLruProcessLocked(ProcessRecord app) {
2662         int lrui = mLruProcesses.lastIndexOf(app);
2663         if (lrui >= 0) {
2664             if (!app.killed) {
2665                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2666                 Process.killProcessQuiet(app.pid);
2667                 Process.killProcessGroup(app.info.uid, app.pid);
2668             }
2669             if (lrui <= mLruProcessActivityStart) {
2670                 mLruProcessActivityStart--;
2671             }
2672             if (lrui <= mLruProcessServiceStart) {
2673                 mLruProcessServiceStart--;
2674             }
2675             mLruProcesses.remove(lrui);
2676         }
2677     }
2678
2679     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2680             ProcessRecord client) {
2681         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2682                 || app.treatLikeActivity;
2683         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2684         if (!activityChange && hasActivity) {
2685             // The process has activities, so we are only allowing activity-based adjustments
2686             // to move it.  It should be kept in the front of the list with other
2687             // processes that have activities, and we don't want those to change their
2688             // order except due to activity operations.
2689             return;
2690         }
2691
2692         mLruSeq++;
2693         final long now = SystemClock.uptimeMillis();
2694         app.lastActivityTime = now;
2695
2696         // First a quick reject: if the app is already at the position we will
2697         // put it, then there is nothing to do.
2698         if (hasActivity) {
2699             final int N = mLruProcesses.size();
2700             if (N > 0 && mLruProcesses.get(N-1) == app) {
2701                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2702                 return;
2703             }
2704         } else {
2705             if (mLruProcessServiceStart > 0
2706                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2707                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2708                 return;
2709             }
2710         }
2711
2712         int lrui = mLruProcesses.lastIndexOf(app);
2713
2714         if (app.persistent && lrui >= 0) {
2715             // We don't care about the position of persistent processes, as long as
2716             // they are in the list.
2717             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2718             return;
2719         }
2720
2721         /* In progress: compute new position first, so we can avoid doing work
2722            if the process is not actually going to move.  Not yet working.
2723         int addIndex;
2724         int nextIndex;
2725         boolean inActivity = false, inService = false;
2726         if (hasActivity) {
2727             // Process has activities, put it at the very tipsy-top.
2728             addIndex = mLruProcesses.size();
2729             nextIndex = mLruProcessServiceStart;
2730             inActivity = true;
2731         } else if (hasService) {
2732             // Process has services, put it at the top of the service list.
2733             addIndex = mLruProcessActivityStart;
2734             nextIndex = mLruProcessServiceStart;
2735             inActivity = true;
2736             inService = true;
2737         } else  {
2738             // Process not otherwise of interest, it goes to the top of the non-service area.
2739             addIndex = mLruProcessServiceStart;
2740             if (client != null) {
2741                 int clientIndex = mLruProcesses.lastIndexOf(client);
2742                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2743                         + app);
2744                 if (clientIndex >= 0 && addIndex > clientIndex) {
2745                     addIndex = clientIndex;
2746                 }
2747             }
2748             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2749         }
2750
2751         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2752                 + mLruProcessActivityStart + "): " + app);
2753         */
2754
2755         if (lrui >= 0) {
2756             if (lrui < mLruProcessActivityStart) {
2757                 mLruProcessActivityStart--;
2758             }
2759             if (lrui < mLruProcessServiceStart) {
2760                 mLruProcessServiceStart--;
2761             }
2762             /*
2763             if (addIndex > lrui) {
2764                 addIndex--;
2765             }
2766             if (nextIndex > lrui) {
2767                 nextIndex--;
2768             }
2769             */
2770             mLruProcesses.remove(lrui);
2771         }
2772
2773         /*
2774         mLruProcesses.add(addIndex, app);
2775         if (inActivity) {
2776             mLruProcessActivityStart++;
2777         }
2778         if (inService) {
2779             mLruProcessActivityStart++;
2780         }
2781         */
2782
2783         int nextIndex;
2784         if (hasActivity) {
2785             final int N = mLruProcesses.size();
2786             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2787                 // Process doesn't have activities, but has clients with
2788                 // activities...  move it up, but one below the top (the top
2789                 // should always have a real activity).
2790                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2791                 mLruProcesses.add(N-1, app);
2792                 // To keep it from spamming the LRU list (by making a bunch of clients),
2793                 // we will push down any other entries owned by the app.
2794                 final int uid = app.info.uid;
2795                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2796                     ProcessRecord subProc = mLruProcesses.get(i);
2797                     if (subProc.info.uid == uid) {
2798                         // We want to push this one down the list.  If the process after
2799                         // it is for the same uid, however, don't do so, because we don't
2800                         // want them internally to be re-ordered.
2801                         if (mLruProcesses.get(i-1).info.uid != uid) {
2802                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2803                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2804                             ProcessRecord tmp = mLruProcesses.get(i);
2805                             mLruProcesses.set(i, mLruProcesses.get(i-1));
2806                             mLruProcesses.set(i-1, tmp);
2807                             i--;
2808                         }
2809                     } else {
2810                         // A gap, we can stop here.
2811                         break;
2812                     }
2813                 }
2814             } else {
2815                 // Process has activities, put it at the very tipsy-top.
2816                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2817                 mLruProcesses.add(app);
2818             }
2819             nextIndex = mLruProcessServiceStart;
2820         } else if (hasService) {
2821             // Process has services, put it at the top of the service list.
2822             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2823             mLruProcesses.add(mLruProcessActivityStart, app);
2824             nextIndex = mLruProcessServiceStart;
2825             mLruProcessActivityStart++;
2826         } else  {
2827             // Process not otherwise of interest, it goes to the top of the non-service area.
2828             int index = mLruProcessServiceStart;
2829             if (client != null) {
2830                 // If there is a client, don't allow the process to be moved up higher
2831                 // in the list than that client.
2832                 int clientIndex = mLruProcesses.lastIndexOf(client);
2833                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2834                         + " when updating " + app);
2835                 if (clientIndex <= lrui) {
2836                     // Don't allow the client index restriction to push it down farther in the
2837                     // list than it already is.
2838                     clientIndex = lrui;
2839                 }
2840                 if (clientIndex >= 0 && index > clientIndex) {
2841                     index = clientIndex;
2842                 }
2843             }
2844             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2845             mLruProcesses.add(index, app);
2846             nextIndex = index-1;
2847             mLruProcessActivityStart++;
2848             mLruProcessServiceStart++;
2849         }
2850
2851         // If the app is currently using a content provider or service,
2852         // bump those processes as well.
2853         for (int j=app.connections.size()-1; j>=0; j--) {
2854             ConnectionRecord cr = app.connections.valueAt(j);
2855             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2856                     && cr.binding.service.app != null
2857                     && cr.binding.service.app.lruSeq != mLruSeq
2858                     && !cr.binding.service.app.persistent) {
2859                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2860                         "service connection", cr, app);
2861             }
2862         }
2863         for (int j=app.conProviders.size()-1; j>=0; j--) {
2864             ContentProviderRecord cpr = app.conProviders.get(j).provider;
2865             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2866                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2867                         "provider reference", cpr, app);
2868             }
2869         }
2870     }
2871
2872     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2873         if (uid == Process.SYSTEM_UID) {
2874             // The system gets to run in any process.  If there are multiple
2875             // processes with the same uid, just pick the first (this
2876             // should never happen).
2877             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2878             if (procs == null) return null;
2879             final int procCount = procs.size();
2880             for (int i = 0; i < procCount; i++) {
2881                 final int procUid = procs.keyAt(i);
2882                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2883                     // Don't use an app process or different user process for system component.
2884                     continue;
2885                 }
2886                 return procs.valueAt(i);
2887             }
2888         }
2889         ProcessRecord proc = mProcessNames.get(processName, uid);
2890         if (false && proc != null && !keepIfLarge
2891                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2892                 && proc.lastCachedPss >= 4000) {
2893             // Turn this condition on to cause killing to happen regularly, for testing.
2894             if (proc.baseProcessTracker != null) {
2895                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2896             }
2897             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2898         } else if (proc != null && !keepIfLarge
2899                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2900                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2901             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2902             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2903                 if (proc.baseProcessTracker != null) {
2904                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2905                 }
2906                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2907             }
2908         }
2909         return proc;
2910     }
2911
2912     void ensurePackageDexOpt(String packageName) {
2913         IPackageManager pm = AppGlobals.getPackageManager();
2914         try {
2915             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2916                 mDidDexOpt = true;
2917             }
2918         } catch (RemoteException e) {
2919         }
2920     }
2921
2922     boolean isNextTransitionForward() {
2923         int transit = mWindowManager.getPendingAppTransition();
2924         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2925                 || transit == AppTransition.TRANSIT_TASK_OPEN
2926                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2927     }
2928
2929     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2930             String processName, String abiOverride, int uid, Runnable crashHandler) {
2931         synchronized(this) {
2932             ApplicationInfo info = new ApplicationInfo();
2933             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2934             // For isolated processes, the former contains the parent's uid and the latter the
2935             // actual uid of the isolated process.
2936             // In the special case introduced by this method (which is, starting an isolated
2937             // process directly from the SystemServer without an actual parent app process) the
2938             // closest thing to a parent's uid is SYSTEM_UID.
2939             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2940             // the |isolated| logic in the ProcessRecord constructor.
2941             info.uid = Process.SYSTEM_UID;
2942             info.processName = processName;
2943             info.className = entryPoint;
2944             info.packageName = "android";
2945             ProcessRecord proc = startProcessLocked(processName, info /* info */,
2946                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2947                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2948                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2949                     crashHandler);
2950             return proc != null ? proc.pid : 0;
2951         }
2952     }
2953
2954     final ProcessRecord startProcessLocked(String processName,
2955             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2956             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2957             boolean isolated, boolean keepIfLarge) {
2958         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2959                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2960                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2961                 null /* crashHandler */);
2962     }
2963
2964     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2965             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2966             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2967             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2968         long startTime = SystemClock.elapsedRealtime();
2969         ProcessRecord app;
2970         if (!isolated) {
2971             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2972             checkTime(startTime, "startProcess: after getProcessRecord");
2973         } else {
2974             // If this is an isolated process, it can't re-use an existing process.
2975             app = null;
2976         }
2977         // We don't have to do anything more if:
2978         // (1) There is an existing application record; and
2979         // (2) The caller doesn't think it is dead, OR there is no thread
2980         //     object attached to it so we know it couldn't have crashed; and
2981         // (3) There is a pid assigned to it, so it is either starting or
2982         //     already running.
2983         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2984                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2985                 + " thread=" + (app != null ? app.thread : null)
2986                 + " pid=" + (app != null ? app.pid : -1));
2987         if (app != null && app.pid > 0) {
2988             if (!knownToBeDead || app.thread == null) {
2989                 // We already have the app running, or are waiting for it to
2990                 // come up (we have a pid but not yet its thread), so keep it.
2991                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2992                 // If this is a new package in the process, add the package to the list
2993                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994                 checkTime(startTime, "startProcess: done, added package to proc");
2995                 return app;
2996             }
2997
2998             // An application record is attached to a previous process,
2999             // clean it up now.
3000             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
3001             checkTime(startTime, "startProcess: bad proc running, killing");
3002             Process.killProcessGroup(app.info.uid, app.pid);
3003             handleAppDiedLocked(app, true, true);
3004             checkTime(startTime, "startProcess: done killing old proc");
3005         }
3006
3007         String hostingNameStr = hostingName != null
3008                 ? hostingName.flattenToShortString() : null;
3009
3010         if (!isolated) {
3011             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3012                 // If we are in the background, then check to see if this process
3013                 // is bad.  If so, we will just silently fail.
3014                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3015                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3016                             + "/" + info.processName);
3017                     return null;
3018                 }
3019             } else {
3020                 // When the user is explicitly starting a process, then clear its
3021                 // crash count so that we won't make it bad until they see at
3022                 // least one crash dialog again, and make the process good again
3023                 // if it had been bad.
3024                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3025                         + "/" + info.processName);
3026                 mProcessCrashTimes.remove(info.processName, info.uid);
3027                 if (mBadProcesses.get(info.processName, info.uid) != null) {
3028                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3029                             UserHandle.getUserId(info.uid), info.uid,
3030                             info.processName);
3031                     mBadProcesses.remove(info.processName, info.uid);
3032                     if (app != null) {
3033                         app.bad = false;
3034                     }
3035                 }
3036             }
3037         }
3038
3039         if (app == null) {
3040             checkTime(startTime, "startProcess: creating new process record");
3041             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3042             app.crashHandler = crashHandler;
3043             if (app == null) {
3044                 Slog.w(TAG, "Failed making new process record for "
3045                         + processName + "/" + info.uid + " isolated=" + isolated);
3046                 return null;
3047             }
3048             mProcessNames.put(processName, app.uid, app);
3049             if (isolated) {
3050                 mIsolatedProcesses.put(app.uid, app);
3051             }
3052             checkTime(startTime, "startProcess: done creating new process record");
3053         } else {
3054             // If this is a new package in the process, add the package to the list
3055             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3056             checkTime(startTime, "startProcess: added package to existing proc");
3057         }
3058
3059         // If the system is not ready yet, then hold off on starting this
3060         // process until it is.
3061         if (!mProcessesReady
3062                 && !isAllowedWhileBooting(info)
3063                 && !allowWhileBooting) {
3064             if (!mProcessesOnHold.contains(app)) {
3065                 mProcessesOnHold.add(app);
3066             }
3067             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3068             checkTime(startTime, "startProcess: returning with proc on hold");
3069             return app;
3070         }
3071
3072         checkTime(startTime, "startProcess: stepping in to startProcess");
3073         startProcessLocked(
3074                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3075         checkTime(startTime, "startProcess: done starting proc!");
3076         return (app.pid != 0) ? app : null;
3077     }
3078
3079     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3080         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3081     }
3082
3083     private final void startProcessLocked(ProcessRecord app,
3084             String hostingType, String hostingNameStr) {
3085         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3086                 null /* entryPoint */, null /* entryPointArgs */);
3087     }
3088
3089     private final void startProcessLocked(ProcessRecord app, String hostingType,
3090             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3091         long startTime = SystemClock.elapsedRealtime();
3092         if (app.pid > 0 && app.pid != MY_PID) {
3093             checkTime(startTime, "startProcess: removing from pids map");
3094             synchronized (mPidsSelfLocked) {
3095                 mPidsSelfLocked.remove(app.pid);
3096                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3097             }
3098             checkTime(startTime, "startProcess: done removing from pids map");
3099             app.setPid(0);
3100         }
3101
3102         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3103                 "startProcessLocked removing on hold: " + app);
3104         mProcessesOnHold.remove(app);
3105
3106         checkTime(startTime, "startProcess: starting to update cpu stats");
3107         updateCpuStats();
3108         checkTime(startTime, "startProcess: done updating cpu stats");
3109
3110         try {
3111             int uid = app.uid;
3112
3113             int[] gids = null;
3114             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3115             if (!app.isolated) {
3116                 int[] permGids = null;
3117                 try {
3118                     checkTime(startTime, "startProcess: getting gids from package manager");
3119                     final PackageManager pm = mContext.getPackageManager();
3120                     permGids = pm.getPackageGids(app.info.packageName);
3121
3122                     if (Environment.isExternalStorageEmulated()) {
3123                         checkTime(startTime, "startProcess: checking external storage perm");
3124                         if (pm.checkPermission(
3125                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3126                                 app.info.packageName) == PERMISSION_GRANTED) {
3127                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3128                         } else {
3129                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3130                         }
3131                     }
3132                 } catch (PackageManager.NameNotFoundException e) {
3133                     Slog.w(TAG, "Unable to retrieve gids", e);
3134                 }
3135
3136                 /*
3137                  * Add shared application and profile GIDs so applications can share some
3138                  * resources like shared libraries and access user-wide resources
3139                  */
3140                 if (permGids == null) {
3141                     gids = new int[2];
3142                 } else {
3143                     gids = new int[permGids.length + 2];
3144                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3145                 }
3146                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3147                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3148             }
3149             checkTime(startTime, "startProcess: building args");
3150             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3151                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3152                         && mTopComponent != null
3153                         && app.processName.equals(mTopComponent.getPackageName())) {
3154                     uid = 0;
3155                 }
3156                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3157                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3158                     uid = 0;
3159                 }
3160             }
3161             int debugFlags = 0;
3162             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3163                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3164                 // Also turn on CheckJNI for debuggable apps. It's quite
3165                 // awkward to turn on otherwise.
3166                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3167             }
3168             // Run the app in safe mode if its manifest requests so or the
3169             // system is booted in safe mode.
3170             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3171                 mSafeMode == true) {
3172                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3173             }
3174             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3175                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3176             }
3177             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3178                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3179             }
3180             if ("1".equals(SystemProperties.get("debug.assert"))) {
3181                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3182             }
3183
3184             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3185             if (requiredAbi == null) {
3186                 requiredAbi = Build.SUPPORTED_ABIS[0];
3187             }
3188
3189             String instructionSet = null;
3190             if (app.info.primaryCpuAbi != null) {
3191                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3192             }
3193
3194             // Start the process.  It will either succeed and return a result containing
3195             // the PID of the new process, or else throw a RuntimeException.
3196             boolean isActivityProcess = (entryPoint == null);
3197             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3198             checkTime(startTime, "startProcess: asking zygote to start proc");
3199             Process.ProcessStartResult startResult = Process.start(entryPoint,
3200                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3201                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3202                     app.info.dataDir, entryPointArgs);
3203             checkTime(startTime, "startProcess: returned from zygote!");
3204
3205             if (app.isolated) {
3206                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3207             }
3208             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3209             checkTime(startTime, "startProcess: done updating battery stats");
3210
3211             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3212                     UserHandle.getUserId(uid), startResult.pid, uid,
3213                     app.processName, hostingType,
3214                     hostingNameStr != null ? hostingNameStr : "");
3215
3216             if (app.persistent) {
3217                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3218             }
3219
3220             checkTime(startTime, "startProcess: building log message");
3221             StringBuilder buf = mStringBuilder;
3222             buf.setLength(0);
3223             buf.append("Start proc ");
3224             buf.append(app.processName);
3225             if (!isActivityProcess) {
3226                 buf.append(" [");
3227                 buf.append(entryPoint);
3228                 buf.append("]");
3229             }
3230             buf.append(" for ");
3231             buf.append(hostingType);
3232             if (hostingNameStr != null) {
3233                 buf.append(" ");
3234                 buf.append(hostingNameStr);
3235             }
3236             buf.append(": pid=");
3237             buf.append(startResult.pid);
3238             buf.append(" uid=");
3239             buf.append(uid);
3240             buf.append(" gids={");
3241             if (gids != null) {
3242                 for (int gi=0; gi<gids.length; gi++) {
3243                     if (gi != 0) buf.append(", ");
3244                     buf.append(gids[gi]);
3245
3246                 }
3247             }
3248             buf.append("}");
3249             if (requiredAbi != null) {
3250                 buf.append(" abi=");
3251                 buf.append(requiredAbi);
3252             }
3253             Slog.i(TAG, buf.toString());
3254             app.setPid(startResult.pid);
3255             app.usingWrapper = startResult.usingWrapper;
3256             app.removed = false;
3257             app.killed = false;
3258             app.killedByAm = false;
3259             checkTime(startTime, "startProcess: starting to update pids map");
3260             synchronized (mPidsSelfLocked) {
3261                 this.mPidsSelfLocked.put(startResult.pid, app);
3262                 if (isActivityProcess) {
3263                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3264                     msg.obj = app;
3265                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3266                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3267                 }
3268             }
3269             checkTime(startTime, "startProcess: done updating pids map");
3270         } catch (RuntimeException e) {
3271             // XXX do better error recovery.
3272             app.setPid(0);
3273             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3274             if (app.isolated) {
3275                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3276             }
3277             Slog.e(TAG, "Failure starting process " + app.processName, e);
3278         }
3279     }
3280
3281     void updateUsageStats(ActivityRecord component, boolean resumed) {
3282         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3283         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3284         if (resumed) {
3285             if (mUsageStatsService != null) {
3286                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3287                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3288             }
3289             synchronized (stats) {
3290                 stats.noteActivityResumedLocked(component.app.uid);
3291             }
3292         } else {
3293             if (mUsageStatsService != null) {
3294                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3295                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3296             }
3297             synchronized (stats) {
3298                 stats.noteActivityPausedLocked(component.app.uid);
3299             }
3300         }
3301     }
3302
3303     Intent getHomeIntent() {
3304         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3305         intent.setComponent(mTopComponent);
3306         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3307             intent.addCategory(Intent.CATEGORY_HOME);
3308         }
3309         return intent;
3310     }
3311
3312     boolean startHomeActivityLocked(int userId) {
3313         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3314                 && mTopAction == null) {
3315             // We are running in factory test mode, but unable to find
3316             // the factory test app, so just sit around displaying the
3317             // error message and don't try to start anything.
3318             return false;
3319         }
3320         Intent intent = getHomeIntent();
3321         ActivityInfo aInfo =
3322             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3323         if (aInfo != null) {
3324             intent.setComponent(new ComponentName(
3325                     aInfo.applicationInfo.packageName, aInfo.name));
3326             // Don't do this if the home app is currently being
3327             // instrumented.
3328             aInfo = new ActivityInfo(aInfo);
3329             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3330             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3331                     aInfo.applicationInfo.uid, true);
3332             if (app == null || app.instrumentationClass == null) {
3333                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3334                 mStackSupervisor.startHomeActivity(intent, aInfo);
3335             }
3336         }
3337
3338         return true;
3339     }
3340
3341     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3342         ActivityInfo ai = null;
3343         ComponentName comp = intent.getComponent();
3344         try {
3345             if (comp != null) {
3346                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3347             } else {
3348                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3349                         intent,
3350                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3351                             flags, userId);
3352
3353                 if (info != null) {
3354                     ai = info.activityInfo;
3355                 }
3356             }
3357         } catch (RemoteException e) {
3358             // ignore
3359         }
3360
3361         return ai;
3362     }
3363
3364     /**
3365      * Starts the "new version setup screen" if appropriate.
3366      */
3367     void startSetupActivityLocked() {
3368         // Only do this once per boot.
3369         if (mCheckedForSetup) {
3370             return;
3371         }
3372
3373         // We will show this screen if the current one is a different
3374         // version than the last one shown, and we are not running in
3375         // low-level factory test mode.
3376         final ContentResolver resolver = mContext.getContentResolver();
3377         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3378                 Settings.Global.getInt(resolver,
3379                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3380             mCheckedForSetup = true;
3381
3382             // See if we should be showing the platform update setup UI.
3383             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3384             List<ResolveInfo> ris = mContext.getPackageManager()
3385                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3386
3387             // We don't allow third party apps to replace this.
3388             ResolveInfo ri = null;
3389             for (int i=0; ris != null && i<ris.size(); i++) {
3390                 if ((ris.get(i).activityInfo.applicationInfo.flags
3391                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3392                     ri = ris.get(i);
3393                     break;
3394                 }
3395             }
3396
3397             if (ri != null) {
3398                 String vers = ri.activityInfo.metaData != null
3399                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3400                         : null;
3401                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3402                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3403                             Intent.METADATA_SETUP_VERSION);
3404                 }
3405                 String lastVers = Settings.Secure.getString(
3406                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3407                 if (vers != null && !vers.equals(lastVers)) {
3408                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3409                     intent.setComponent(new ComponentName(
3410                             ri.activityInfo.packageName, ri.activityInfo.name));
3411                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3412                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3413                             null);
3414                 }
3415             }
3416         }
3417     }
3418
3419     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3420         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3421     }
3422
3423     void enforceNotIsolatedCaller(String caller) {
3424         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3425             throw new SecurityException("Isolated process not allowed to call " + caller);
3426         }
3427     }
3428
3429     void enforceShellRestriction(String restriction, int userHandle) {
3430         if (Binder.getCallingUid() == Process.SHELL_UID) {
3431             if (userHandle < 0
3432                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3433                 throw new SecurityException("Shell does not have permission to access user "
3434                         + userHandle);
3435             }
3436         }
3437     }
3438
3439     @Override
3440     public int getFrontActivityScreenCompatMode() {
3441         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3442         synchronized (this) {
3443             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3444         }
3445     }
3446
3447     @Override
3448     public void setFrontActivityScreenCompatMode(int mode) {
3449         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3450                 "setFrontActivityScreenCompatMode");
3451         synchronized (this) {
3452             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3453         }
3454     }
3455
3456     @Override
3457     public int getPackageScreenCompatMode(String packageName) {
3458         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3459         synchronized (this) {
3460             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3461         }
3462     }
3463
3464     @Override
3465     public void setPackageScreenCompatMode(String packageName, int mode) {
3466         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3467                 "setPackageScreenCompatMode");
3468         synchronized (this) {
3469             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3470         }
3471     }
3472
3473     @Override
3474     public boolean getPackageAskScreenCompat(String packageName) {
3475         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3476         synchronized (this) {
3477             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3478         }
3479     }
3480
3481     @Override
3482     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3483         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3484                 "setPackageAskScreenCompat");
3485         synchronized (this) {
3486             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3487         }
3488     }
3489
3490     private void dispatchProcessesChanged() {
3491         int N;
3492         synchronized (this) {
3493             N = mPendingProcessChanges.size();
3494             if (mActiveProcessChanges.length < N) {
3495                 mActiveProcessChanges = new ProcessChangeItem[N];
3496             }
3497             mPendingProcessChanges.toArray(mActiveProcessChanges);
3498             mAvailProcessChanges.addAll(mPendingProcessChanges);
3499             mPendingProcessChanges.clear();
3500             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3501         }
3502
3503         int i = mProcessObservers.beginBroadcast();
3504         while (i > 0) {
3505             i--;
3506             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3507             if (observer != null) {
3508                 try {
3509                     for (int j=0; j<N; j++) {
3510                         ProcessChangeItem item = mActiveProcessChanges[j];
3511                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3512                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3513                                     + item.pid + " uid=" + item.uid + ": "
3514                                     + item.foregroundActivities);
3515                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3516                                     item.foregroundActivities);
3517                         }
3518                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3519                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3520                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
3521                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3522                         }
3523                     }
3524                 } catch (RemoteException e) {
3525                 }
3526             }
3527         }
3528         mProcessObservers.finishBroadcast();
3529     }
3530
3531     private void dispatchProcessDied(int pid, int uid) {
3532         int i = mProcessObservers.beginBroadcast();
3533         while (i > 0) {
3534             i--;
3535             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3536             if (observer != null) {
3537                 try {
3538                     observer.onProcessDied(pid, uid);
3539                 } catch (RemoteException e) {
3540                 }
3541             }
3542         }
3543         mProcessObservers.finishBroadcast();
3544     }
3545
3546     @Override
3547     public final int startActivity(IApplicationThread caller, String callingPackage,
3548             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3549             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3550         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3551             resultWho, requestCode, startFlags, profilerInfo, options,
3552             UserHandle.getCallingUserId());
3553     }
3554
3555     @Override
3556     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3557             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3558             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3559         enforceNotIsolatedCaller("startActivity");
3560         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3561                 false, ALLOW_FULL_ONLY, "startActivity", null);
3562         // TODO: Switch to user app stacks here.
3563         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3564                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3565                 profilerInfo, null, null, options, userId, null, null);
3566     }
3567
3568     @Override
3569     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3570             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3571             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3572
3573         // This is very dangerous -- it allows you to perform a start activity (including
3574         // permission grants) as any app that may launch one of your own activities.  So
3575         // we will only allow this to be done from activities that are part of the core framework,
3576         // and then only when they are running as the system.
3577         final ActivityRecord sourceRecord;
3578         final int targetUid;
3579         final String targetPackage;
3580         synchronized (this) {
3581             if (resultTo == null) {
3582                 throw new SecurityException("Must be called from an activity");
3583             }
3584             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3585             if (sourceRecord == null) {
3586                 throw new SecurityException("Called with bad activity token: " + resultTo);
3587             }
3588             if (!sourceRecord.info.packageName.equals("android")) {
3589                 throw new SecurityException(
3590                         "Must be called from an activity that is declared in the android package");
3591             }
3592             if (sourceRecord.app == null) {
3593                 throw new SecurityException("Called without a process attached to activity");
3594             }
3595             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3596                 // This is still okay, as long as this activity is running under the
3597                 // uid of the original calling activity.
3598                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3599                     throw new SecurityException(
3600                             "Calling activity in uid " + sourceRecord.app.uid
3601                                     + " must be system uid or original calling uid "
3602                                     + sourceRecord.launchedFromUid);
3603                 }
3604             }
3605             targetUid = sourceRecord.launchedFromUid;
3606             targetPackage = sourceRecord.launchedFromPackage;
3607         }
3608
3609         if (userId == UserHandle.USER_NULL) {
3610             userId = UserHandle.getUserId(sourceRecord.app.uid);
3611         }
3612
3613         // TODO: Switch to user app stacks here.
3614         try {
3615             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3616                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3617                     null, null, options, userId, null, null);
3618             return ret;
3619         } catch (SecurityException e) {
3620             // XXX need to figure out how to propagate to original app.
3621             // A SecurityException here is generally actually a fault of the original
3622             // calling activity (such as a fairly granting permissions), so propagate it
3623             // back to them.
3624             /*
3625             StringBuilder msg = new StringBuilder();
3626             msg.append("While launching");
3627             msg.append(intent.toString());
3628             msg.append(": ");
3629             msg.append(e.getMessage());
3630             */
3631             throw e;
3632         }
3633     }
3634
3635     @Override
3636     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3637             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3638             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3639         enforceNotIsolatedCaller("startActivityAndWait");
3640         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3641                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3642         WaitResult res = new WaitResult();
3643         // TODO: Switch to user app stacks here.
3644         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3645                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3646                 options, userId, null, null);
3647         return res;
3648     }
3649
3650     @Override
3651     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3652             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3653             int startFlags, Configuration config, Bundle options, int userId) {
3654         enforceNotIsolatedCaller("startActivityWithConfig");
3655         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3656                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3657         // TODO: Switch to user app stacks here.
3658         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3659                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3660                 null, null, config, options, userId, null, null);
3661         return ret;
3662     }
3663
3664     @Override
3665     public int startActivityIntentSender(IApplicationThread caller,
3666             IntentSender intent, Intent fillInIntent, String resolvedType,
3667             IBinder resultTo, String resultWho, int requestCode,
3668             int flagsMask, int flagsValues, Bundle options) {
3669         enforceNotIsolatedCaller("startActivityIntentSender");
3670         // Refuse possible leaked file descriptors
3671         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3672             throw new IllegalArgumentException("File descriptors passed in Intent");
3673         }
3674
3675         IIntentSender sender = intent.getTarget();
3676         if (!(sender instanceof PendingIntentRecord)) {
3677             throw new IllegalArgumentException("Bad PendingIntent object");
3678         }
3679
3680         PendingIntentRecord pir = (PendingIntentRecord)sender;
3681
3682         synchronized (this) {
3683             // If this is coming from the currently resumed activity, it is
3684             // effectively saying that app switches are allowed at this point.
3685             final ActivityStack stack = getFocusedStack();
3686             if (stack.mResumedActivity != null &&
3687                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3688                 mAppSwitchesAllowedTime = 0;
3689             }
3690         }
3691         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3692                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3693         return ret;
3694     }
3695
3696     @Override
3697     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3698             Intent intent, String resolvedType, IVoiceInteractionSession session,
3699             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3700             Bundle options, int userId) {
3701         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3702                 != PackageManager.PERMISSION_GRANTED) {
3703             String msg = "Permission Denial: startVoiceActivity() from pid="
3704                     + Binder.getCallingPid()
3705                     + ", uid=" + Binder.getCallingUid()
3706                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3707             Slog.w(TAG, msg);
3708             throw new SecurityException(msg);
3709         }
3710         if (session == null || interactor == null) {
3711             throw new NullPointerException("null session or interactor");
3712         }
3713         userId = handleIncomingUser(callingPid, callingUid, userId,
3714                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3715         // TODO: Switch to user app stacks here.
3716         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3717                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3718                 null, options, userId, null, null);
3719     }
3720
3721     @Override
3722     public boolean startNextMatchingActivity(IBinder callingActivity,
3723             Intent intent, Bundle options) {
3724         // Refuse possible leaked file descriptors
3725         if (intent != null && intent.hasFileDescriptors() == true) {
3726             throw new IllegalArgumentException("File descriptors passed in Intent");
3727         }
3728
3729         synchronized (this) {
3730             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3731             if (r == null) {
3732                 ActivityOptions.abort(options);
3733                 return false;
3734             }
3735             if (r.app == null || r.app.thread == null) {
3736                 // The caller is not running...  d'oh!
3737                 ActivityOptions.abort(options);
3738                 return false;
3739             }
3740             intent = new Intent(intent);
3741             // The caller is not allowed to change the data.
3742             intent.setDataAndType(r.intent.getData(), r.intent.getType());
3743             // And we are resetting to find the next component...
3744             intent.setComponent(null);
3745
3746             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3747
3748             ActivityInfo aInfo = null;
3749             try {
3750                 List<ResolveInfo> resolves =
3751                     AppGlobals.getPackageManager().queryIntentActivities(
3752                             intent, r.resolvedType,
3753                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3754                             UserHandle.getCallingUserId());
3755
3756                 // Look for the original activity in the list...
3757                 final int N = resolves != null ? resolves.size() : 0;
3758                 for (int i=0; i<N; i++) {
3759                     ResolveInfo rInfo = resolves.get(i);
3760                     if (rInfo.activityInfo.packageName.equals(r.packageName)
3761                             && rInfo.activityInfo.name.equals(r.info.name)) {
3762                         // We found the current one...  the next matching is
3763                         // after it.
3764                         i++;
3765                         if (i<N) {
3766                             aInfo = resolves.get(i).activityInfo;
3767                         }
3768                         if (debug) {
3769                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
3770                                     + "/" + r.info.name);
3771                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3772                                     + "/" + aInfo.name);
3773                         }
3774                         break;
3775                     }
3776                 }
3777             } catch (RemoteException e) {
3778             }
3779
3780             if (aInfo == null) {
3781                 // Nobody who is next!
3782                 ActivityOptions.abort(options);
3783                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3784                 return false;
3785             }
3786
3787             intent.setComponent(new ComponentName(
3788                     aInfo.applicationInfo.packageName, aInfo.name));
3789             intent.setFlags(intent.getFlags()&~(
3790                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3791                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
3792                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3793                     Intent.FLAG_ACTIVITY_NEW_TASK));
3794
3795             // Okay now we need to start the new activity, replacing the
3796             // currently running activity.  This is a little tricky because
3797             // we want to start the new one as if the current one is finished,
3798             // but not finish the current one first so that there is no flicker.
3799             // And thus...
3800             final boolean wasFinishing = r.finishing;
3801             r.finishing = true;
3802
3803             // Propagate reply information over to the new activity.
3804             final ActivityRecord resultTo = r.resultTo;
3805             final String resultWho = r.resultWho;
3806             final int requestCode = r.requestCode;
3807             r.resultTo = null;
3808             if (resultTo != null) {
3809                 resultTo.removeResultsLocked(r, resultWho, requestCode);
3810             }
3811
3812             final long origId = Binder.clearCallingIdentity();
3813             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3814                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3815                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3816                     -1, r.launchedFromUid, 0, options, false, null, null, null);
3817             Binder.restoreCallingIdentity(origId);
3818
3819             r.finishing = wasFinishing;
3820             if (res != ActivityManager.START_SUCCESS) {
3821                 return false;
3822             }
3823             return true;
3824         }
3825     }
3826
3827     @Override
3828     public final int startActivityFromRecents(int taskId, Bundle options) {
3829         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3830             String msg = "Permission Denial: startActivityFromRecents called without " +
3831                     START_TASKS_FROM_RECENTS;
3832             Slog.w(TAG, msg);
3833             throw new SecurityException(msg);
3834         }
3835         return startActivityFromRecentsInner(taskId, options);
3836     }
3837
3838     final int startActivityFromRecentsInner(int taskId, Bundle options) {
3839         final TaskRecord task;
3840         final int callingUid;
3841         final String callingPackage;
3842         final Intent intent;
3843         final int userId;
3844         synchronized (this) {
3845             task = recentTaskForIdLocked(taskId);
3846             if (task == null) {
3847                 throw new IllegalArgumentException("Task " + taskId + " not found.");
3848             }
3849             callingUid = task.mCallingUid;
3850             callingPackage = task.mCallingPackage;
3851             intent = task.intent;
3852             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3853             userId = task.userId;
3854         }
3855         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3856                 options, userId, null, task);
3857     }
3858
3859     final int startActivityInPackage(int uid, String callingPackage,
3860             Intent intent, String resolvedType, IBinder resultTo,
3861             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3862             IActivityContainer container, TaskRecord inTask) {
3863
3864         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3865                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3866
3867         // TODO: Switch to user app stacks here.
3868         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3869                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3870                 null, null, null, options, userId, container, inTask);
3871         return ret;
3872     }
3873
3874     @Override
3875     public final int startActivities(IApplicationThread caller, String callingPackage,
3876             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3877             int userId) {
3878         enforceNotIsolatedCaller("startActivities");
3879         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3880                 false, ALLOW_FULL_ONLY, "startActivity", null);
3881         // TODO: Switch to user app stacks here.
3882         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3883                 resolvedTypes, resultTo, options, userId);
3884         return ret;
3885     }
3886
3887     final int startActivitiesInPackage(int uid, String callingPackage,
3888             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3889             Bundle options, int userId) {
3890
3891         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3892                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3893         // TODO: Switch to user app stacks here.
3894         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3895                 resultTo, options, userId);
3896         return ret;
3897     }
3898
3899     //explicitly remove thd old information in mRecentTasks when removing existing user.
3900     private void removeRecentTasksForUserLocked(int userId) {
3901         if(userId <= 0) {
3902             Slog.i(TAG, "Can't remove recent task on user " + userId);
3903             return;
3904         }
3905
3906         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3907             TaskRecord tr = mRecentTasks.get(i);
3908             if (tr.userId == userId) {
3909                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3910                         + " when finishing user" + userId);
3911                 mRecentTasks.remove(i);
3912                 tr.removedFromRecents(mTaskPersister);
3913             }
3914         }
3915
3916         // Remove tasks from persistent storage.
3917         mTaskPersister.wakeup(null, true);
3918     }
3919
3920     // Sort by taskId
3921     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3922         @Override
3923         public int compare(TaskRecord lhs, TaskRecord rhs) {
3924             return rhs.taskId - lhs.taskId;
3925         }
3926     };
3927
3928     // Extract the affiliates of the chain containing mRecentTasks[start].
3929     private int processNextAffiliateChain(int start) {
3930         final TaskRecord startTask = mRecentTasks.get(start);
3931         final int affiliateId = startTask.mAffiliatedTaskId;
3932
3933         // Quick identification of isolated tasks. I.e. those not launched behind.
3934         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3935                 startTask.mNextAffiliate == null) {
3936             // There is still a slim chance that there are other tasks that point to this task
3937             // and that the chain is so messed up that this task no longer points to them but
3938             // the gain of this optimization outweighs the risk.
3939             startTask.inRecents = true;
3940             return start + 1;
3941         }
3942
3943         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3944         mTmpRecents.clear();
3945         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3946             final TaskRecord task = mRecentTasks.get(i);
3947             if (task.mAffiliatedTaskId == affiliateId) {
3948                 mRecentTasks.remove(i);
3949                 mTmpRecents.add(task);
3950             }
3951         }
3952
3953         // Sort them all by taskId. That is the order they were create in and that order will
3954         // always be correct.
3955         Collections.sort(mTmpRecents, mTaskRecordComparator);
3956
3957         // Go through and fix up the linked list.
3958         // The first one is the end of the chain and has no next.
3959         final TaskRecord first = mTmpRecents.get(0);
3960         first.inRecents = true;
3961         if (first.mNextAffiliate != null) {
3962             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3963             first.setNextAffiliate(null);
3964             mTaskPersister.wakeup(first, false);
3965         }
3966         // Everything in the middle is doubly linked from next to prev.
3967         final int tmpSize = mTmpRecents.size();
3968         for (int i = 0; i < tmpSize - 1; ++i) {
3969             final TaskRecord next = mTmpRecents.get(i);
3970             final TaskRecord prev = mTmpRecents.get(i + 1);
3971             if (next.mPrevAffiliate != prev) {
3972                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3973                         " setting prev=" + prev);
3974                 next.setPrevAffiliate(prev);
3975                 mTaskPersister.wakeup(next, false);
3976             }
3977             if (prev.mNextAffiliate != next) {
3978                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3979                         " setting next=" + next);
3980                 prev.setNextAffiliate(next);
3981                 mTaskPersister.wakeup(prev, false);
3982             }
3983             prev.inRecents = true;
3984         }
3985         // The last one is the beginning of the list and has no prev.
3986         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3987         if (last.mPrevAffiliate != null) {
3988             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3989             last.setPrevAffiliate(null);
3990             mTaskPersister.wakeup(last, false);
3991         }
3992
3993         // Insert the group back into mRecentTasks at start.
3994         mRecentTasks.addAll(start, mTmpRecents);
3995
3996         // Let the caller know where we left off.
3997         return start + tmpSize;
3998     }
3999
4000     /**
4001      * Update the recent tasks lists: make sure tasks should still be here (their
4002      * applications / activities still exist), update their availability, fixup ordering
4003      * of affiliations.
4004      */
4005     void cleanupRecentTasksLocked(int userId) {
4006         if (mRecentTasks == null) {
4007             // Happens when called from the packagemanager broadcast before boot.
4008             return;
4009         }
4010
4011         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4012         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4013         final IPackageManager pm = AppGlobals.getPackageManager();
4014         final ActivityInfo dummyAct = new ActivityInfo();
4015         final ApplicationInfo dummyApp = new ApplicationInfo();
4016
4017         int N = mRecentTasks.size();
4018
4019         int[] users = userId == UserHandle.USER_ALL
4020                 ? getUsersLocked() : new int[] { userId };
4021         for (int user : users) {
4022             for (int i = 0; i < N; i++) {
4023                 TaskRecord task = mRecentTasks.get(i);
4024                 if (task.userId != user) {
4025                     // Only look at tasks for the user ID of interest.
4026                     continue;
4027                 }
4028                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
4029                     // This situation is broken, and we should just get rid of it now.
4030                     mRecentTasks.remove(i);
4031                     task.removedFromRecents(mTaskPersister);
4032                     i--;
4033                     N--;
4034                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
4035                     continue;
4036                 }
4037                 // Check whether this activity is currently available.
4038                 if (task.realActivity != null) {
4039                     ActivityInfo ai = availActCache.get(task.realActivity);
4040                     if (ai == null) {
4041                         try {
4042                             ai = pm.getActivityInfo(task.realActivity,
4043                                     PackageManager.GET_UNINSTALLED_PACKAGES
4044                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
4045                         } catch (RemoteException e) {
4046                             // Will never happen.
4047                             continue;
4048                         }
4049                         if (ai == null) {
4050                             ai = dummyAct;
4051                         }
4052                         availActCache.put(task.realActivity, ai);
4053                     }
4054                     if (ai == dummyAct) {
4055                         // This could be either because the activity no longer exists, or the
4056                         // app is temporarily gone.  For the former we want to remove the recents
4057                         // entry; for the latter we want to mark it as unavailable.
4058                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4059                         if (app == null) {
4060                             try {
4061                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4062                                         PackageManager.GET_UNINSTALLED_PACKAGES
4063                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
4064                             } catch (RemoteException e) {
4065                                 // Will never happen.
4066                                 continue;
4067                             }
4068                             if (app == null) {
4069                                 app = dummyApp;
4070                             }
4071                             availAppCache.put(task.realActivity.getPackageName(), app);
4072                         }
4073                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4074                             // Doesn't exist any more!  Good-bye.
4075                             mRecentTasks.remove(i);
4076                             task.removedFromRecents(mTaskPersister);
4077                             i--;
4078                             N--;
4079                             Slog.w(TAG, "Removing no longer valid recent: " + task);
4080                             continue;
4081                         } else {
4082                             // Otherwise just not available for now.
4083                             if (task.isAvailable) {
4084                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4085                                         + task);
4086                             }
4087                             task.isAvailable = false;
4088                         }
4089                     } else {
4090                         if (!ai.enabled || !ai.applicationInfo.enabled
4091                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4092                             if (task.isAvailable) {
4093                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4094                                         + task + " (enabled=" + ai.enabled + "/"
4095                                         + ai.applicationInfo.enabled +  " flags="
4096                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
4097                             }
4098                             task.isAvailable = false;
4099                         } else {
4100                             if (!task.isAvailable) {
4101                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4102                                         + task);
4103                             }
4104                             task.isAvailable = true;
4105                         }
4106                     }
4107                 }
4108             }
4109         }
4110
4111         // Verify the affiliate chain for each task.
4112         for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4113         }
4114
4115         mTmpRecents.clear();
4116         // mRecentTasks is now in sorted, affiliated order.
4117     }
4118
4119     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4120         int N = mRecentTasks.size();
4121         TaskRecord top = task;
4122         int topIndex = taskIndex;
4123         while (top.mNextAffiliate != null && topIndex > 0) {
4124             top = top.mNextAffiliate;
4125             topIndex--;
4126         }
4127         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4128                 + topIndex + " from intial " + taskIndex);
4129         // Find the end of the chain, doing a sanity check along the way.
4130         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4131         int endIndex = topIndex;
4132         TaskRecord prev = top;
4133         while (endIndex < N) {
4134             TaskRecord cur = mRecentTasks.get(endIndex);
4135             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4136                     + endIndex + " " + cur);
4137             if (cur == top) {
4138                 // Verify start of the chain.
4139                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4140                     Slog.wtf(TAG, "Bad chain @" + endIndex
4141                             + ": first task has next affiliate: " + prev);
4142                     sane = false;
4143                     break;
4144                 }
4145             } else {
4146                 // Verify middle of the chain's next points back to the one before.
4147                 if (cur.mNextAffiliate != prev
4148                         || cur.mNextAffiliateTaskId != prev.taskId) {
4149                     Slog.wtf(TAG, "Bad chain @" + endIndex
4150                             + ": middle task " + cur + " @" + endIndex
4151                             + " has bad next affiliate "
4152                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4153                             + ", expected " + prev);
4154                     sane = false;
4155                     break;
4156                 }
4157             }
4158             if (cur.mPrevAffiliateTaskId == -1) {
4159                 // Chain ends here.
4160                 if (cur.mPrevAffiliate != null) {
4161                     Slog.wtf(TAG, "Bad chain @" + endIndex
4162                             + ": last task " + cur + " has previous affiliate "
4163                             + cur.mPrevAffiliate);
4164                     sane = false;
4165                 }
4166                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4167                 break;
4168             } else {
4169                 // Verify middle of the chain's prev points to a valid item.
4170                 if (cur.mPrevAffiliate == null) {
4171                     Slog.wtf(TAG, "Bad chain @" + endIndex
4172                             + ": task " + cur + " has previous affiliate "
4173                             + cur.mPrevAffiliate + " but should be id "
4174                             + cur.mPrevAffiliate);
4175                     sane = false;
4176                     break;
4177                 }
4178             }
4179             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4180                 Slog.wtf(TAG, "Bad chain @" + endIndex
4181                         + ": task " + cur + " has affiliated id "
4182                         + cur.mAffiliatedTaskId + " but should be "
4183                         + task.mAffiliatedTaskId);
4184                 sane = false;
4185                 break;
4186             }
4187             prev = cur;
4188             endIndex++;
4189             if (endIndex >= N) {
4190                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4191                         + ": last task " + prev);
4192                 sane = false;
4193                 break;
4194             }
4195         }
4196         if (sane) {
4197             if (endIndex < taskIndex) {
4198                 Slog.wtf(TAG, "Bad chain @" + endIndex
4199                         + ": did not extend to task " + task + " @" + taskIndex);
4200                 sane = false;
4201             }
4202         }
4203         if (sane) {
4204             // All looks good, we can just move all of the affiliated tasks
4205             // to the top.
4206             for (int i=topIndex; i<=endIndex; i++) {
4207                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4208                         + " from " + i + " to " + (i-topIndex));
4209                 TaskRecord cur = mRecentTasks.remove(i);
4210                 mRecentTasks.add(i-topIndex, cur);
4211             }
4212             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4213                     + " to " + endIndex);
4214             return true;
4215         }
4216
4217         // Whoops, couldn't do it.
4218         return false;
4219     }
4220
4221     final void addRecentTaskLocked(TaskRecord task) {
4222         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4223                 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4224
4225         int N = mRecentTasks.size();
4226         // Quick case: check if the top-most recent task is the same.
4227         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4228             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4229             return;
4230         }
4231         // Another quick case: check if this is part of a set of affiliated
4232         // tasks that are at the top.
4233         if (isAffiliated && N > 0 && task.inRecents
4234                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4235             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4236                     + " at top when adding " + task);
4237             return;
4238         }
4239         // Another quick case: never add voice sessions.
4240         if (task.voiceSession != null) {
4241             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4242             return;
4243         }
4244
4245         boolean needAffiliationFix = false;
4246
4247         // Slightly less quick case: the task is already in recents, so all we need
4248         // to do is move it.
4249         if (task.inRecents) {
4250             int taskIndex = mRecentTasks.indexOf(task);
4251             if (taskIndex >= 0) {
4252                 if (!isAffiliated) {
4253                     // Simple case: this is not an affiliated task, so we just move it to the front.
4254                     mRecentTasks.remove(taskIndex);
4255                     mRecentTasks.add(0, task);
4256                     notifyTaskPersisterLocked(task, false);
4257                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4258                             + " from " + taskIndex);
4259                     return;
4260                 } else {
4261                     // More complicated: need to keep all affiliated tasks together.
4262                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4263                         // All went well.
4264                         return;
4265                     }
4266
4267                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4268                     // everything and then go through our general path of adding a new task.
4269                     needAffiliationFix = true;
4270                 }
4271             } else {
4272                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4273                 needAffiliationFix = true;
4274             }
4275         }
4276
4277         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4278         trimRecentsForTask(task, true);
4279
4280         N = mRecentTasks.size();
4281         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4282             final TaskRecord tr = mRecentTasks.remove(N - 1);
4283             tr.removedFromRecents(mTaskPersister);
4284             N--;
4285         }
4286         task.inRecents = true;
4287         if (!isAffiliated || needAffiliationFix) {
4288             // If this is a simple non-affiliated task, or we had some failure trying to
4289             // handle it as part of an affilated task, then just place it at the top.
4290             mRecentTasks.add(0, task);
4291         } else if (isAffiliated) {
4292             // If this is a new affiliated task, then move all of the affiliated tasks
4293             // to the front and insert this new one.
4294             TaskRecord other = task.mNextAffiliate;
4295             if (other == null) {
4296                 other = task.mPrevAffiliate;
4297             }
4298             if (other != null) {
4299                 int otherIndex = mRecentTasks.indexOf(other);
4300                 if (otherIndex >= 0) {
4301                     // Insert new task at appropriate location.
4302                     int taskIndex;
4303                     if (other == task.mNextAffiliate) {
4304                         // We found the index of our next affiliation, which is who is
4305                         // before us in the list, so add after that point.
4306                         taskIndex = otherIndex+1;
4307                     } else {
4308                         // We found the index of our previous affiliation, which is who is
4309                         // after us in the list, so add at their position.
4310                         taskIndex = otherIndex;
4311                     }
4312                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4313                             + taskIndex + ": " + task);
4314                     mRecentTasks.add(taskIndex, task);
4315
4316                     // Now move everything to the front.
4317                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4318                         // All went well.
4319                         return;
4320                     }
4321
4322                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4323                     // everything and then go through our general path of adding a new task.
4324                     needAffiliationFix = true;
4325                 } else {
4326                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4327                             + other);
4328                     needAffiliationFix = true;
4329                 }
4330             } else {
4331                 if (DEBUG_RECENTS) Slog.d(TAG,
4332                         "addRecent: adding affiliated task without next/prev:" + task);
4333                 needAffiliationFix = true;
4334             }
4335         }
4336         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4337
4338         if (needAffiliationFix) {
4339             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4340             cleanupRecentTasksLocked(task.userId);
4341         }
4342     }
4343
4344     /**
4345      * If needed, remove oldest existing entries in recents that are for the same kind
4346      * of task as the given one.
4347      */
4348     int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4349         int N = mRecentTasks.size();
4350         final Intent intent = task.intent;
4351         final boolean document = intent != null && intent.isDocument();
4352
4353         int maxRecents = task.maxRecents - 1;
4354         for (int i=0; i<N; i++) {
4355             final TaskRecord tr = mRecentTasks.get(i);
4356             if (task != tr) {
4357                 if (task.userId != tr.userId) {
4358                     continue;
4359                 }
4360                 if (i > MAX_RECENT_BITMAPS) {
4361                     tr.freeLastThumbnail();
4362                 }
4363                 final Intent trIntent = tr.intent;
4364                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4365                     (intent == null || !intent.filterEquals(trIntent))) {
4366                     continue;
4367                 }
4368                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4369                 if (document && trIsDocument) {
4370                     // These are the same document activity (not necessarily the same doc).
4371                     if (maxRecents > 0) {
4372                         --maxRecents;
4373                         continue;
4374                     }
4375                     // Hit the maximum number of documents for this task. Fall through
4376                     // and remove this document from recents.
4377                 } else if (document || trIsDocument) {
4378                     // Only one of these is a document. Not the droid we're looking for.
4379                     continue;
4380                 }
4381             }
4382
4383             if (!doTrim) {
4384                 // If the caller is not actually asking for a trim, just tell them we reached
4385                 // a point where the trim would happen.
4386                 return i;
4387             }
4388
4389             // Either task and tr are the same or, their affinities match or their intents match
4390             // and neither of them is a document, or they are documents using the same activity
4391             // and their maxRecents has been reached.
4392             tr.disposeThumbnail();
4393             mRecentTasks.remove(i);
4394             if (task != tr) {
4395                 tr.removedFromRecents(mTaskPersister);
4396             }
4397             i--;
4398             N--;
4399             if (task.intent == null) {
4400                 // If the new recent task we are adding is not fully
4401                 // specified, then replace it with the existing recent task.
4402                 task = tr;
4403             }
4404             notifyTaskPersisterLocked(tr, false);
4405         }
4406
4407         return -1;
4408     }
4409
4410     @Override
4411     public void reportActivityFullyDrawn(IBinder token) {
4412         synchronized (this) {
4413             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4414             if (r == null) {
4415                 return;
4416             }
4417             r.reportFullyDrawnLocked();
4418         }
4419     }
4420
4421     @Override
4422     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4423         synchronized (this) {
4424             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425             if (r == null) {
4426                 return;
4427             }
4428             final long origId = Binder.clearCallingIdentity();
4429             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4430             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4431                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4432             if (config != null) {
4433                 r.frozenBeforeDestroy = true;
4434                 if (!updateConfigurationLocked(config, r, false, false)) {
4435                     mStackSupervisor.resumeTopActivitiesLocked();
4436                 }
4437             }
4438             Binder.restoreCallingIdentity(origId);
4439         }
4440     }
4441
4442     @Override
4443     public int getRequestedOrientation(IBinder token) {
4444         synchronized (this) {
4445             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4446             if (r == null) {
4447                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4448             }
4449             return mWindowManager.getAppOrientation(r.appToken);
4450         }
4451     }
4452
4453     /**
4454      * This is the internal entry point for handling Activity.finish().
4455      *
4456      * @param token The Binder token referencing the Activity we want to finish.
4457      * @param resultCode Result code, if any, from this Activity.
4458      * @param resultData Result data (Intent), if any, from this Activity.
4459      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4460      *            the root Activity in the task.
4461      *
4462      * @return Returns true if the activity successfully finished, or false if it is still running.
4463      */
4464     @Override
4465     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4466             boolean finishTask) {
4467         // Refuse possible leaked file descriptors
4468         if (resultData != null && resultData.hasFileDescriptors() == true) {
4469             throw new IllegalArgumentException("File descriptors passed in Intent");
4470         }
4471
4472         synchronized(this) {
4473             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4474             if (r == null) {
4475                 return true;
4476             }
4477             // Keep track of the root activity of the task before we finish it
4478             TaskRecord tr = r.task;
4479             ActivityRecord rootR = tr.getRootActivity();
4480             // Do not allow task to finish in Lock Task mode.
4481             if (tr == mStackSupervisor.mLockTaskModeTask) {
4482                 if (rootR == r) {
4483                     mStackSupervisor.showLockTaskToast();
4484                     return false;
4485                 }
4486             }
4487             if (mController != null) {
4488                 // Find the first activity that is not finishing.
4489                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4490                 if (next != null) {
4491                     // ask watcher if this is allowed
4492                     boolean resumeOK = true;
4493                     try {
4494                         resumeOK = mController.activityResuming(next.packageName);
4495                     } catch (RemoteException e) {
4496                         mController = null;
4497                         Watchdog.getInstance().setActivityController(null);
4498                     }
4499
4500                     if (!resumeOK) {
4501                         return false;
4502                     }
4503                 }
4504             }
4505             final long origId = Binder.clearCallingIdentity();
4506             try {
4507                 boolean res;
4508                 if (finishTask && r == rootR) {
4509                     // If requested, remove the task that is associated to this activity only if it
4510                     // was the root activity in the task.  The result code and data is ignored because
4511                     // we don't support returning them across task boundaries.
4512                     res = removeTaskByIdLocked(tr.taskId, 0);
4513                 } else {
4514                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4515                             resultData, "app-request", true);
4516                 }
4517                 return res;
4518             } finally {
4519                 Binder.restoreCallingIdentity(origId);
4520             }
4521         }
4522     }
4523
4524     @Override
4525     public final void finishHeavyWeightApp() {
4526         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4527                 != PackageManager.PERMISSION_GRANTED) {
4528             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4529                     + Binder.getCallingPid()
4530                     + ", uid=" + Binder.getCallingUid()
4531                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4532             Slog.w(TAG, msg);
4533             throw new SecurityException(msg);
4534         }
4535
4536         synchronized(this) {
4537             if (mHeavyWeightProcess == null) {
4538                 return;
4539             }
4540
4541             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4542                     mHeavyWeightProcess.activities);
4543             for (int i=0; i<activities.size(); i++) {
4544                 ActivityRecord r = activities.get(i);
4545                 if (!r.finishing) {
4546                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4547                             null, "finish-heavy", true);
4548                 }
4549             }
4550
4551             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4552                     mHeavyWeightProcess.userId, 0));
4553             mHeavyWeightProcess = null;
4554         }
4555     }
4556
4557     @Override
4558     public void crashApplication(int uid, int initialPid, String packageName,
4559             String message) {
4560         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4561                 != PackageManager.PERMISSION_GRANTED) {
4562             String msg = "Permission Denial: crashApplication() from pid="
4563                     + Binder.getCallingPid()
4564                     + ", uid=" + Binder.getCallingUid()
4565                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4566             Slog.w(TAG, msg);
4567             throw new SecurityException(msg);
4568         }
4569
4570         synchronized(this) {
4571             ProcessRecord proc = null;
4572
4573             // Figure out which process to kill.  We don't trust that initialPid
4574             // still has any relation to current pids, so must scan through the
4575             // list.
4576             synchronized (mPidsSelfLocked) {
4577                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4578                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4579                     if (p.uid != uid) {
4580                         continue;
4581                     }
4582                     if (p.pid == initialPid) {
4583                         proc = p;
4584                         break;
4585                     }
4586                     if (p.pkgList.containsKey(packageName)) {
4587                         proc = p;
4588                     }
4589                 }
4590             }
4591
4592             if (proc == null) {
4593                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4594                         + " initialPid=" + initialPid
4595                         + " packageName=" + packageName);
4596                 return;
4597             }
4598
4599             if (proc.thread != null) {
4600                 if (proc.pid == Process.myPid()) {
4601                     Log.w(TAG, "crashApplication: trying to crash self!");
4602                     return;
4603                 }
4604                 long ident = Binder.clearCallingIdentity();
4605                 try {
4606                     proc.thread.scheduleCrash(message);
4607                 } catch (RemoteException e) {
4608                 }
4609                 Binder.restoreCallingIdentity(ident);
4610             }
4611         }
4612     }
4613
4614     @Override
4615     public final void finishSubActivity(IBinder token, String resultWho,
4616             int requestCode) {
4617         synchronized(this) {
4618             final long origId = Binder.clearCallingIdentity();
4619             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4620             if (r != null) {
4621                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4622             }
4623             Binder.restoreCallingIdentity(origId);
4624         }
4625     }
4626
4627     @Override
4628     public boolean finishActivityAffinity(IBinder token) {
4629         synchronized(this) {
4630             final long origId = Binder.clearCallingIdentity();
4631             try {
4632                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4633
4634                 ActivityRecord rootR = r.task.getRootActivity();
4635                 // Do not allow task to finish in Lock Task mode.
4636                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4637                     if (rootR == r) {
4638                         mStackSupervisor.showLockTaskToast();
4639                         return false;
4640                     }
4641                 }
4642                 boolean res = false;
4643                 if (r != null) {
4644                     res = r.task.stack.finishActivityAffinityLocked(r);
4645                 }
4646                 return res;
4647             } finally {
4648                 Binder.restoreCallingIdentity(origId);
4649             }
4650         }
4651     }
4652
4653     @Override
4654     public void finishVoiceTask(IVoiceInteractionSession session) {
4655         synchronized(this) {
4656             final long origId = Binder.clearCallingIdentity();
4657             try {
4658                 mStackSupervisor.finishVoiceTask(session);
4659             } finally {
4660                 Binder.restoreCallingIdentity(origId);
4661             }
4662         }
4663
4664     }
4665
4666     @Override
4667     public boolean releaseActivityInstance(IBinder token) {
4668         synchronized(this) {
4669             final long origId = Binder.clearCallingIdentity();
4670             try {
4671                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4672                 if (r.task == null || r.task.stack == null) {
4673                     return false;
4674                 }
4675                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4676             } finally {
4677                 Binder.restoreCallingIdentity(origId);
4678             }
4679         }
4680     }
4681
4682     @Override
4683     public void releaseSomeActivities(IApplicationThread appInt) {
4684         synchronized(this) {
4685             final long origId = Binder.clearCallingIdentity();
4686             try {
4687                 ProcessRecord app = getRecordForAppLocked(appInt);
4688                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4689             } finally {
4690                 Binder.restoreCallingIdentity(origId);
4691             }
4692         }
4693     }
4694
4695     @Override
4696     public boolean willActivityBeVisible(IBinder token) {
4697         synchronized(this) {
4698             ActivityStack stack = ActivityRecord.getStackLocked(token);
4699             if (stack != null) {
4700                 return stack.willActivityBeVisibleLocked(token);
4701             }
4702             return false;
4703         }
4704     }
4705
4706     @Override
4707     public void overridePendingTransition(IBinder token, String packageName,
4708             int enterAnim, int exitAnim) {
4709         synchronized(this) {
4710             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4711             if (self == null) {
4712                 return;
4713             }
4714
4715             final long origId = Binder.clearCallingIdentity();
4716
4717             if (self.state == ActivityState.RESUMED
4718                     || self.state == ActivityState.PAUSING) {
4719                 mWindowManager.overridePendingAppTransition(packageName,
4720                         enterAnim, exitAnim, null);
4721             }
4722
4723             Binder.restoreCallingIdentity(origId);
4724         }
4725     }
4726
4727     /**
4728      * Main function for removing an existing process from the activity manager
4729      * as a result of that process going away.  Clears out all connections
4730      * to the process.
4731      */
4732     private final void handleAppDiedLocked(ProcessRecord app,
4733             boolean restarting, boolean allowRestart) {
4734         int pid = app.pid;
4735         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4736         if (!kept && !restarting) {
4737             removeLruProcessLocked(app);
4738             if (pid > 0) {
4739                 ProcessList.remove(pid);
4740             }
4741         }
4742
4743         if (mProfileProc == app) {
4744             clearProfilerLocked();
4745         }
4746
4747         // Remove this application's activities from active lists.
4748         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4749
4750         app.activities.clear();
4751
4752         if (app.instrumentationClass != null) {
4753             Slog.w(TAG, "Crash of app " + app.processName
4754                   + " running instrumentation " + app.instrumentationClass);
4755             Bundle info = new Bundle();
4756             info.putString("shortMsg", "Process crashed.");
4757             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4758         }
4759
4760         if (!restarting) {
4761             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4762                 // If there was nothing to resume, and we are not already
4763                 // restarting this process, but there is a visible activity that
4764                 // is hosted by the process...  then make sure all visible
4765                 // activities are running, taking care of restarting this
4766                 // process.
4767                 if (hasVisibleActivities) {
4768                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4769                 }
4770             }
4771         }
4772     }
4773
4774     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4775         IBinder threadBinder = thread.asBinder();
4776         // Find the application record.
4777         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4778             ProcessRecord rec = mLruProcesses.get(i);
4779             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4780                 return i;
4781             }
4782         }
4783         return -1;
4784     }
4785
4786     final ProcessRecord getRecordForAppLocked(
4787             IApplicationThread thread) {
4788         if (thread == null) {
4789             return null;
4790         }
4791
4792         int appIndex = getLRURecordIndexForAppLocked(thread);
4793         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4794     }
4795
4796     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4797         // If there are no longer any background processes running,
4798         // and the app that died was not running instrumentation,
4799         // then tell everyone we are now low on memory.
4800         boolean haveBg = false;
4801         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4802             ProcessRecord rec = mLruProcesses.get(i);
4803             if (rec.thread != null
4804                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4805                 haveBg = true;
4806                 break;
4807             }
4808         }
4809
4810         if (!haveBg) {
4811             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4812             if (doReport) {
4813                 long now = SystemClock.uptimeMillis();
4814                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4815                     doReport = false;
4816                 } else {
4817                     mLastMemUsageReportTime = now;
4818                 }
4819             }
4820             final ArrayList<ProcessMemInfo> memInfos
4821                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4822             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4823             long now = SystemClock.uptimeMillis();
4824             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4825                 ProcessRecord rec = mLruProcesses.get(i);
4826                 if (rec == dyingProc || rec.thread == null) {
4827                     continue;
4828                 }
4829                 if (doReport) {
4830                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4831                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4832                 }
4833                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4834                     // The low memory report is overriding any current
4835                     // state for a GC request.  Make sure to do
4836                     // heavy/important/visible/foreground processes first.
4837                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4838                         rec.lastRequestedGc = 0;
4839                     } else {
4840                         rec.lastRequestedGc = rec.lastLowMemory;
4841                     }
4842                     rec.reportLowMemory = true;
4843                     rec.lastLowMemory = now;
4844                     mProcessesToGc.remove(rec);
4845                     addProcessToGcListLocked(rec);
4846                 }
4847             }
4848             if (doReport) {
4849                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4850                 mHandler.sendMessage(msg);
4851             }
4852             scheduleAppGcsLocked();
4853         }
4854     }
4855
4856     final void appDiedLocked(ProcessRecord app) {
4857        appDiedLocked(app, app.pid, app.thread);
4858     }
4859
4860     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4861         // First check if this ProcessRecord is actually active for the pid.
4862         synchronized (mPidsSelfLocked) {
4863             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4864             if (curProc != app) {
4865                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4866                 return;
4867             }
4868         }
4869
4870         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4871         synchronized (stats) {
4872             stats.noteProcessDiedLocked(app.info.uid, pid);
4873         }
4874
4875         Process.killProcessQuiet(pid);
4876         Process.killProcessGroup(app.info.uid, pid);
4877         app.killed = true;
4878
4879         // Clean up already done if the process has been re-started.
4880         if (app.pid == pid && app.thread != null &&
4881                 app.thread.asBinder() == thread.asBinder()) {
4882             boolean doLowMem = app.instrumentationClass == null;
4883             boolean doOomAdj = doLowMem;
4884             if (!app.killedByAm) {
4885                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4886                         + ") has died");
4887                 mAllowLowerMemLevel = true;
4888             } else {
4889                 // Note that we always want to do oom adj to update our state with the
4890                 // new number of procs.
4891                 mAllowLowerMemLevel = false;
4892                 doLowMem = false;
4893             }
4894             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4895             if (DEBUG_CLEANUP) Slog.v(
4896                 TAG, "Dying app: " + app + ", pid: " + pid
4897                 + ", thread: " + thread.asBinder());
4898             handleAppDiedLocked(app, false, true);
4899
4900             if (doOomAdj) {
4901                 updateOomAdjLocked();
4902             }
4903             if (doLowMem) {
4904                 doLowMemReportIfNeededLocked(app);
4905             }
4906         } else if (app.pid != pid) {
4907             // A new process has already been started.
4908             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4909                     + ") has died and restarted (pid " + app.pid + ").");
4910             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4911         } else if (DEBUG_PROCESSES) {
4912             Slog.d(TAG, "Received spurious death notification for thread "
4913                     + thread.asBinder());
4914         }
4915     }
4916
4917     /**
4918      * If a stack trace dump file is configured, dump process stack traces.
4919      * @param clearTraces causes the dump file to be erased prior to the new
4920      *    traces being written, if true; when false, the new traces will be
4921      *    appended to any existing file content.
4922      * @param firstPids of dalvik VM processes to dump stack traces for first
4923      * @param lastPids of dalvik VM processes to dump stack traces for last
4924      * @param nativeProcs optional list of native process names to dump stack crawls
4925      * @return file containing stack traces, or null if no dump file is configured
4926      */
4927     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4928             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4929         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4930         if (tracesPath == null || tracesPath.length() == 0) {
4931             return null;
4932         }
4933
4934         File tracesFile = new File(tracesPath);
4935         try {
4936             File tracesDir = tracesFile.getParentFile();
4937             if (!tracesDir.exists()) {
4938                 tracesDir.mkdirs();
4939                 if (!SELinux.restorecon(tracesDir)) {
4940                     return null;
4941                 }
4942             }
4943             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4944
4945             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4946             tracesFile.createNewFile();
4947             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4948         } catch (IOException e) {
4949             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4950             return null;
4951         }
4952
4953         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4954         return tracesFile;
4955     }
4956
4957     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4958             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4959         // Use a FileObserver to detect when traces finish writing.
4960         // The order of traces is considered important to maintain for legibility.
4961         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4962             @Override
4963             public synchronized void onEvent(int event, String path) { notify(); }
4964         };
4965
4966         try {
4967             observer.startWatching();
4968
4969             // First collect all of the stacks of the most important pids.
4970             if (firstPids != null) {
4971                 try {
4972                     int num = firstPids.size();
4973                     for (int i = 0; i < num; i++) {
4974                         synchronized (observer) {
4975                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4976                             observer.wait(200);  // Wait for write-close, give up after 200msec
4977                         }
4978                     }
4979                 } catch (InterruptedException e) {
4980                     Slog.wtf(TAG, e);
4981                 }
4982             }
4983
4984             // Next collect the stacks of the native pids
4985             if (nativeProcs != null) {
4986                 int[] pids = Process.getPidsForCommands(nativeProcs);
4987                 if (pids != null) {
4988                     for (int pid : pids) {
4989                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4990                     }
4991                 }
4992             }
4993
4994             // Lastly, measure CPU usage.
4995             if (processCpuTracker != null) {
4996                 processCpuTracker.init();
4997                 System.gc();
4998                 processCpuTracker.update();
4999                 try {
5000                     synchronized (processCpuTracker) {
5001                         processCpuTracker.wait(500); // measure over 1/2 second.
5002                     }
5003                 } catch (InterruptedException e) {
5004                 }
5005                 processCpuTracker.update();
5006
5007                 // We'll take the stack crawls of just the top apps using CPU.
5008                 final int N = processCpuTracker.countWorkingStats();
5009                 int numProcs = 0;
5010                 for (int i=0; i<N && numProcs<5; i++) {
5011                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5012                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5013                         numProcs++;
5014                         try {
5015                             synchronized (observer) {
5016                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5017                                 observer.wait(200);  // Wait for write-close, give up after 200msec
5018                             }
5019                         } catch (InterruptedException e) {
5020                             Slog.wtf(TAG, e);
5021                         }
5022
5023                     }
5024                 }
5025             }
5026         } finally {
5027             observer.stopWatching();
5028         }
5029     }
5030
5031     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5032         if (true || IS_USER_BUILD) {
5033             return;
5034         }
5035         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5036         if (tracesPath == null || tracesPath.length() == 0) {
5037             return;
5038         }
5039
5040         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5041         StrictMode.allowThreadDiskWrites();
5042         try {
5043             final File tracesFile = new File(tracesPath);
5044             final File tracesDir = tracesFile.getParentFile();
5045             final File tracesTmp = new File(tracesDir, "__tmp__");
5046             try {
5047                 if (!tracesDir.exists()) {
5048                     tracesDir.mkdirs();
5049                     if (!SELinux.restorecon(tracesDir.getPath())) {
5050                         return;
5051                     }
5052                 }
5053                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5054
5055                 if (tracesFile.exists()) {
5056                     tracesTmp.delete();
5057                     tracesFile.renameTo(tracesTmp);
5058                 }
5059                 StringBuilder sb = new StringBuilder();
5060                 Time tobj = new Time();
5061                 tobj.set(System.currentTimeMillis());
5062                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5063                 sb.append(": ");
5064                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5065                 sb.append(" since ");
5066                 sb.append(msg);
5067                 FileOutputStream fos = new FileOutputStream(tracesFile);
5068                 fos.write(sb.toString().getBytes());
5069                 if (app == null) {
5070                     fos.write("\n*** No application process!".getBytes());
5071                 }
5072                 fos.close();
5073                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5074             } catch (IOException e) {
5075                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5076                 return;
5077             }
5078
5079             if (app != null) {
5080                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5081                 firstPids.add(app.pid);
5082                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5083             }
5084
5085             File lastTracesFile = null;
5086             File curTracesFile = null;
5087             for (int i=9; i>=0; i--) {
5088                 String name = String.format(Locale.US, "slow%02d.txt", i);
5089                 curTracesFile = new File(tracesDir, name);
5090                 if (curTracesFile.exists()) {
5091                     if (lastTracesFile != null) {
5092                         curTracesFile.renameTo(lastTracesFile);
5093                     } else {
5094                         curTracesFile.delete();
5095                     }
5096                 }
5097                 lastTracesFile = curTracesFile;
5098             }
5099             tracesFile.renameTo(curTracesFile);
5100             if (tracesTmp.exists()) {
5101                 tracesTmp.renameTo(tracesFile);
5102             }
5103         } finally {
5104             StrictMode.setThreadPolicy(oldPolicy);
5105         }
5106     }
5107
5108     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5109             ActivityRecord parent, boolean aboveSystem, final String annotation) {
5110         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5111         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5112
5113         if (mController != null) {
5114             try {
5115                 // 0 == continue, -1 = kill process immediately
5116                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5117                 if (res < 0 && app.pid != MY_PID) {
5118                     app.kill("anr", true);
5119                 }
5120             } catch (RemoteException e) {
5121                 mController = null;
5122                 Watchdog.getInstance().setActivityController(null);
5123             }
5124         }
5125
5126         long anrTime = SystemClock.uptimeMillis();
5127         if (MONITOR_CPU_USAGE) {
5128             updateCpuStatsNow();
5129         }
5130
5131         synchronized (this) {
5132             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5133             if (mShuttingDown) {
5134                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5135                 return;
5136             } else if (app.notResponding) {
5137                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5138                 return;
5139             } else if (app.crashing) {
5140                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5141                 return;
5142             }
5143
5144             // In case we come through here for the same app before completing
5145             // this one, mark as anring now so we will bail out.
5146             app.notResponding = true;
5147
5148             // Log the ANR to the event log.
5149             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5150                     app.processName, app.info.flags, annotation);
5151
5152             // Dump thread traces as quickly as we can, starting with "interesting" processes.
5153             firstPids.add(app.pid);
5154
5155             int parentPid = app.pid;
5156             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5157             if (parentPid != app.pid) firstPids.add(parentPid);
5158
5159             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5160
5161             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5162                 ProcessRecord r = mLruProcesses.get(i);
5163                 if (r != null && r.thread != null) {
5164                     int pid = r.pid;
5165                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5166                         if (r.persistent) {
5167                             firstPids.add(pid);
5168                         } else {
5169                             lastPids.put(pid, Boolean.TRUE);
5170                         }
5171                     }
5172                 }
5173             }
5174         }
5175
5176         // Log the ANR to the main log.
5177         StringBuilder info = new StringBuilder();
5178         info.setLength(0);
5179         info.append("ANR in ").append(app.processName);
5180         if (activity != null && activity.shortComponentName != null) {
5181             info.append(" (").append(activity.shortComponentName).append(")");
5182         }
5183         info.append("\n");
5184         info.append("PID: ").append(app.pid).append("\n");
5185         if (annotation != null) {
5186             info.append("Reason: ").append(annotation).append("\n");
5187         }
5188         if (parent != null && parent != activity) {
5189             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5190         }
5191
5192         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5193
5194         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5195                 NATIVE_STACKS_OF_INTEREST);
5196
5197         String cpuInfo = null;
5198         if (MONITOR_CPU_USAGE) {
5199             updateCpuStatsNow();
5200             synchronized (mProcessCpuTracker) {
5201                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5202             }
5203             info.append(processCpuTracker.printCurrentLoad());
5204             info.append(cpuInfo);
5205         }
5206
5207         info.append(processCpuTracker.printCurrentState(anrTime));
5208
5209         Slog.e(TAG, info.toString());
5210         if (tracesFile == null) {
5211             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5212             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5213         }
5214
5215         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5216                 cpuInfo, tracesFile, null);
5217
5218         if (mController != null) {
5219             try {
5220                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5221                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5222                 if (res != 0) {
5223                     if (res < 0 && app.pid != MY_PID) {
5224                         app.kill("anr", true);
5225                     } else {
5226                         synchronized (this) {
5227                             mServices.scheduleServiceTimeoutLocked(app);
5228                         }
5229                     }
5230                     return;
5231                 }
5232             } catch (RemoteException e) {
5233                 mController = null;
5234                 Watchdog.getInstance().setActivityController(null);
5235             }
5236         }
5237
5238         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5239         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5240                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5241
5242         synchronized (this) {
5243             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5244                 app.kill("bg anr", true);
5245                 return;
5246             }
5247
5248             // Set the app's notResponding state, and look up the errorReportReceiver
5249             makeAppNotRespondingLocked(app,
5250                     activity != null ? activity.shortComponentName : null,
5251                     annotation != null ? "ANR " + annotation : "ANR",
5252                     info.toString());
5253
5254             // Bring up the infamous App Not Responding dialog
5255             Message msg = Message.obtain();
5256             HashMap<String, Object> map = new HashMap<String, Object>();
5257             msg.what = SHOW_NOT_RESPONDING_MSG;
5258             msg.obj = map;
5259             msg.arg1 = aboveSystem ? 1 : 0;
5260             map.put("app", app);
5261             if (activity != null) {
5262                 map.put("activity", activity);
5263             }
5264
5265             mHandler.sendMessage(msg);
5266         }
5267     }
5268
5269     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5270         if (!mLaunchWarningShown) {
5271             mLaunchWarningShown = true;
5272             mHandler.post(new Runnable() {
5273                 @Override
5274                 public void run() {
5275                     synchronized (ActivityManagerService.this) {
5276                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5277                         d.show();
5278                         mHandler.postDelayed(new Runnable() {
5279                             @Override
5280                             public void run() {
5281                                 synchronized (ActivityManagerService.this) {
5282                                     d.dismiss();
5283                                     mLaunchWarningShown = false;
5284                                 }
5285                             }
5286                         }, 4000);
5287                     }
5288                 }
5289             });
5290         }
5291     }
5292
5293     @Override
5294     public boolean clearApplicationUserData(final String packageName,
5295             final IPackageDataObserver observer, int userId) {
5296         enforceNotIsolatedCaller("clearApplicationUserData");
5297         int uid = Binder.getCallingUid();
5298         int pid = Binder.getCallingPid();
5299         userId = handleIncomingUser(pid, uid,
5300                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5301         long callingId = Binder.clearCallingIdentity();
5302         try {
5303             IPackageManager pm = AppGlobals.getPackageManager();
5304             int pkgUid = -1;
5305             synchronized(this) {
5306                 try {
5307                     pkgUid = pm.getPackageUid(packageName, userId);
5308                 } catch (RemoteException e) {
5309                 }
5310                 if (pkgUid == -1) {
5311                     Slog.w(TAG, "Invalid packageName: " + packageName);
5312                     if (observer != null) {
5313                         try {
5314                             observer.onRemoveCompleted(packageName, false);
5315                         } catch (RemoteException e) {
5316                             Slog.i(TAG, "Observer no longer exists.");
5317                         }
5318                     }
5319                     return false;
5320                 }
5321                 if (uid == pkgUid || checkComponentPermission(
5322                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5323                         pid, uid, -1, true)
5324                         == PackageManager.PERMISSION_GRANTED) {
5325                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5326                 } else {
5327                     throw new SecurityException("PID " + pid + " does not have permission "
5328                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5329                                     + " of package " + packageName);
5330                 }
5331
5332                 // Remove all tasks match the cleared application package and user
5333                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5334                     final TaskRecord tr = mRecentTasks.get(i);
5335                     final String taskPackageName =
5336                             tr.getBaseIntent().getComponent().getPackageName();
5337                     if (tr.userId != userId) continue;
5338                     if (!taskPackageName.equals(packageName)) continue;
5339                     removeTaskByIdLocked(tr.taskId, 0);
5340                 }
5341             }
5342
5343             try {
5344                 // Clear application user data
5345                 pm.clearApplicationUserData(packageName, observer, userId);
5346
5347                 synchronized(this) {
5348                     // Remove all permissions granted from/to this package
5349                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5350                 }
5351
5352                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5353                         Uri.fromParts("package", packageName, null));
5354                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5355                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5356                         null, null, 0, null, null, null, false, false, userId);
5357             } catch (RemoteException e) {
5358             }
5359         } finally {
5360             Binder.restoreCallingIdentity(callingId);
5361         }
5362         return true;
5363     }
5364
5365     @Override
5366     public void killBackgroundProcesses(final String packageName, int userId) {
5367         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5368                 != PackageManager.PERMISSION_GRANTED &&
5369                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5370                         != PackageManager.PERMISSION_GRANTED) {
5371             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5372                     + Binder.getCallingPid()
5373                     + ", uid=" + Binder.getCallingUid()
5374                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5375             Slog.w(TAG, msg);
5376             throw new SecurityException(msg);
5377         }
5378
5379         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5380                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5381         long callingId = Binder.clearCallingIdentity();
5382         try {
5383             IPackageManager pm = AppGlobals.getPackageManager();
5384             synchronized(this) {
5385                 int appId = -1;
5386                 try {
5387                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5388                 } catch (RemoteException e) {
5389                 }
5390                 if (appId == -1) {
5391                     Slog.w(TAG, "Invalid packageName: " + packageName);
5392                     return;
5393                 }
5394                 killPackageProcessesLocked(packageName, appId, userId,
5395                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5396             }
5397         } finally {
5398             Binder.restoreCallingIdentity(callingId);
5399         }
5400     }
5401
5402     @Override
5403     public void killAllBackgroundProcesses() {
5404         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5405                 != PackageManager.PERMISSION_GRANTED) {
5406             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5407                     + Binder.getCallingPid()
5408                     + ", uid=" + Binder.getCallingUid()
5409                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5410             Slog.w(TAG, msg);
5411             throw new SecurityException(msg);
5412         }
5413
5414         long callingId = Binder.clearCallingIdentity();
5415         try {
5416             synchronized(this) {
5417                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5418                 final int NP = mProcessNames.getMap().size();
5419                 for (int ip=0; ip<NP; ip++) {
5420                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5421                     final int NA = apps.size();
5422                     for (int ia=0; ia<NA; ia++) {
5423                         ProcessRecord app = apps.valueAt(ia);
5424                         if (app.persistent) {
5425                             // we don't kill persistent processes
5426                             continue;
5427                         }
5428                         if (app.removed) {
5429                             procs.add(app);
5430                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5431                             app.removed = true;
5432                             procs.add(app);
5433                         }
5434                     }
5435                 }
5436
5437                 int N = procs.size();
5438                 for (int i=0; i<N; i++) {
5439                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5440                 }
5441                 mAllowLowerMemLevel = true;
5442                 updateOomAdjLocked();
5443                 doLowMemReportIfNeededLocked(null);
5444             }
5445         } finally {
5446             Binder.restoreCallingIdentity(callingId);
5447         }
5448     }
5449
5450     @Override
5451     public void forceStopPackage(final String packageName, int userId) {
5452         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5453                 != PackageManager.PERMISSION_GRANTED) {
5454             String msg = "Permission Denial: forceStopPackage() from pid="
5455                     + Binder.getCallingPid()
5456                     + ", uid=" + Binder.getCallingUid()
5457                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5458             Slog.w(TAG, msg);
5459             throw new SecurityException(msg);
5460         }
5461         final int callingPid = Binder.getCallingPid();
5462         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5463                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5464         long callingId = Binder.clearCallingIdentity();
5465         try {
5466             IPackageManager pm = AppGlobals.getPackageManager();
5467             synchronized(this) {
5468                 int[] users = userId == UserHandle.USER_ALL
5469                         ? getUsersLocked() : new int[] { userId };
5470                 for (int user : users) {
5471                     int pkgUid = -1;
5472                     try {
5473                         pkgUid = pm.getPackageUid(packageName, user);
5474                     } catch (RemoteException e) {
5475                     }
5476                     if (pkgUid == -1) {
5477                         Slog.w(TAG, "Invalid packageName: " + packageName);
5478                         continue;
5479                     }
5480                     try {
5481                         pm.setPackageStoppedState(packageName, true, user);
5482                     } catch (RemoteException e) {
5483                     } catch (IllegalArgumentException e) {
5484                         Slog.w(TAG, "Failed trying to unstop package "
5485                                 + packageName + ": " + e);
5486                     }
5487                     if (isUserRunningLocked(user, false)) {
5488                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5489                     }
5490                 }
5491             }
5492         } finally {
5493             Binder.restoreCallingIdentity(callingId);
5494         }
5495     }
5496
5497     @Override
5498     public void addPackageDependency(String packageName) {
5499         synchronized (this) {
5500             int callingPid = Binder.getCallingPid();
5501             if (callingPid == Process.myPid()) {
5502                 //  Yeah, um, no.
5503                 Slog.w(TAG, "Can't addPackageDependency on system process");
5504                 return;
5505             }
5506             ProcessRecord proc;
5507             synchronized (mPidsSelfLocked) {
5508                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5509             }
5510             if (proc != null) {
5511                 if (proc.pkgDeps == null) {
5512                     proc.pkgDeps = new ArraySet<String>(1);
5513                 }
5514                 proc.pkgDeps.add(packageName);
5515             }
5516         }
5517     }
5518
5519     /*
5520      * The pkg name and app id have to be specified.
5521      */
5522     @Override
5523     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5524         if (pkg == null) {
5525             return;
5526         }
5527         // Make sure the uid is valid.
5528         if (appid < 0) {
5529             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5530             return;
5531         }
5532         int callerUid = Binder.getCallingUid();
5533         // Only the system server can kill an application
5534         if (callerUid == Process.SYSTEM_UID) {
5535             // Post an aysnc message to kill the application
5536             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5537             msg.arg1 = appid;
5538             msg.arg2 = 0;
5539             Bundle bundle = new Bundle();
5540             bundle.putString("pkg", pkg);
5541             bundle.putString("reason", reason);
5542             msg.obj = bundle;
5543             mHandler.sendMessage(msg);
5544         } else {
5545             throw new SecurityException(callerUid + " cannot kill pkg: " +
5546                     pkg);
5547         }
5548     }
5549
5550     @Override
5551     public void closeSystemDialogs(String reason) {
5552         enforceNotIsolatedCaller("closeSystemDialogs");
5553
5554         final int pid = Binder.getCallingPid();
5555         final int uid = Binder.getCallingUid();
5556         final long origId = Binder.clearCallingIdentity();
5557         try {
5558             synchronized (this) {
5559                 // Only allow this from foreground processes, so that background
5560                 // applications can't abuse it to prevent system UI from being shown.
5561                 if (uid >= Process.FIRST_APPLICATION_UID) {
5562                     ProcessRecord proc;
5563                     synchronized (mPidsSelfLocked) {
5564                         proc = mPidsSelfLocked.get(pid);
5565                     }
5566                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5567                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5568                                 + " from background process " + proc);
5569                         return;
5570                     }
5571                 }
5572                 closeSystemDialogsLocked(reason);
5573             }
5574         } finally {
5575             Binder.restoreCallingIdentity(origId);
5576         }
5577     }
5578
5579     void closeSystemDialogsLocked(String reason) {
5580         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5581         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5582                 | Intent.FLAG_RECEIVER_FOREGROUND);
5583         if (reason != null) {
5584             intent.putExtra("reason", reason);
5585         }
5586         mWindowManager.closeSystemDialogs(reason);
5587
5588         mStackSupervisor.closeSystemDialogsLocked();
5589
5590         broadcastIntentLocked(null, null, intent, null,
5591                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5592                 Process.SYSTEM_UID, UserHandle.USER_ALL);
5593     }
5594
5595     @Override
5596     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5597         enforceNotIsolatedCaller("getProcessMemoryInfo");
5598         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5599         for (int i=pids.length-1; i>=0; i--) {
5600             ProcessRecord proc;
5601             int oomAdj;
5602             synchronized (this) {
5603                 synchronized (mPidsSelfLocked) {
5604                     proc = mPidsSelfLocked.get(pids[i]);
5605                     oomAdj = proc != null ? proc.setAdj : 0;
5606                 }
5607             }
5608             infos[i] = new Debug.MemoryInfo();
5609             Debug.getMemoryInfo(pids[i], infos[i]);
5610             if (proc != null) {
5611                 synchronized (this) {
5612                     if (proc.thread != null && proc.setAdj == oomAdj) {
5613                         // Record this for posterity if the process has been stable.
5614                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5615                                 infos[i].getTotalUss(), false, proc.pkgList);
5616                     }
5617                 }
5618             }
5619         }
5620         return infos;
5621     }
5622
5623     @Override
5624     public long[] getProcessPss(int[] pids) {
5625         enforceNotIsolatedCaller("getProcessPss");
5626         long[] pss = new long[pids.length];
5627         for (int i=pids.length-1; i>=0; i--) {
5628             ProcessRecord proc;
5629             int oomAdj;
5630             synchronized (this) {
5631                 synchronized (mPidsSelfLocked) {
5632                     proc = mPidsSelfLocked.get(pids[i]);
5633                     oomAdj = proc != null ? proc.setAdj : 0;
5634                 }
5635             }
5636             long[] tmpUss = new long[1];
5637             pss[i] = Debug.getPss(pids[i], tmpUss);
5638             if (proc != null) {
5639                 synchronized (this) {
5640                     if (proc.thread != null && proc.setAdj == oomAdj) {
5641                         // Record this for posterity if the process has been stable.
5642                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5643                     }
5644                 }
5645             }
5646         }
5647         return pss;
5648     }
5649
5650     @Override
5651     public void killApplicationProcess(String processName, int uid) {
5652         if (processName == null) {
5653             return;
5654         }
5655
5656         int callerUid = Binder.getCallingUid();
5657         // Only the system server can kill an application
5658         if (callerUid == Process.SYSTEM_UID) {
5659             synchronized (this) {
5660                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5661                 if (app != null && app.thread != null) {
5662                     try {
5663                         app.thread.scheduleSuicide();
5664                     } catch (RemoteException e) {
5665                         // If the other end already died, then our work here is done.
5666                     }
5667                 } else {
5668                     Slog.w(TAG, "Process/uid not found attempting kill of "
5669                             + processName + " / " + uid);
5670                 }
5671             }
5672         } else {
5673             throw new SecurityException(callerUid + " cannot kill app process: " +
5674                     processName);
5675         }
5676     }
5677
5678     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5679         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5680                 false, true, false, false, UserHandle.getUserId(uid), reason);
5681         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5682                 Uri.fromParts("package", packageName, null));
5683         if (!mProcessesReady) {
5684             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5685                     | Intent.FLAG_RECEIVER_FOREGROUND);
5686         }
5687         intent.putExtra(Intent.EXTRA_UID, uid);
5688         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5689         broadcastIntentLocked(null, null, intent,
5690                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5691                 false, false,
5692                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5693     }
5694
5695     private void forceStopUserLocked(int userId, String reason) {
5696         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5697         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5698         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5699                 | Intent.FLAG_RECEIVER_FOREGROUND);
5700         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5701         broadcastIntentLocked(null, null, intent,
5702                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5703                 false, false,
5704                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5705     }
5706
5707     private final boolean killPackageProcessesLocked(String packageName, int appId,
5708             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5709             boolean doit, boolean evenPersistent, String reason) {
5710         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5711
5712         // Remove all processes this package may have touched: all with the
5713         // same UID (except for the system or root user), and all whose name
5714         // matches the package name.
5715         final int NP = mProcessNames.getMap().size();
5716         for (int ip=0; ip<NP; ip++) {
5717             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5718             final int NA = apps.size();
5719             for (int ia=0; ia<NA; ia++) {
5720                 ProcessRecord app = apps.valueAt(ia);
5721                 if (app.persistent && !evenPersistent) {
5722                     // we don't kill persistent processes
5723                     continue;
5724                 }
5725                 if (app.removed) {
5726                     if (doit) {
5727                         procs.add(app);
5728                     }
5729                     continue;
5730                 }
5731
5732                 // Skip process if it doesn't meet our oom adj requirement.
5733                 if (app.setAdj < minOomAdj) {
5734                     continue;
5735                 }
5736
5737                 // If no package is specified, we call all processes under the
5738                 // give user id.
5739                 if (packageName == null) {
5740                     if (app.userId != userId) {
5741                         continue;
5742                     }
5743                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5744                         continue;
5745                     }
5746                 // Package has been specified, we want to hit all processes
5747                 // that match it.  We need to qualify this by the processes
5748                 // that are running under the specified app and user ID.
5749                 } else {
5750                     final boolean isDep = app.pkgDeps != null
5751                             && app.pkgDeps.contains(packageName);
5752                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5753                         continue;
5754                     }
5755                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5756                         continue;
5757                     }
5758                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5759                         continue;
5760                     }
5761                 }
5762
5763                 // Process has passed all conditions, kill it!
5764                 if (!doit) {
5765                     return true;
5766                 }
5767                 app.removed = true;
5768                 procs.add(app);
5769             }
5770         }
5771
5772         int N = procs.size();
5773         for (int i=0; i<N; i++) {
5774             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5775         }
5776         updateOomAdjLocked();
5777         return N > 0;
5778     }
5779
5780     private final boolean forceStopPackageLocked(String name, int appId,
5781             boolean callerWillRestart, boolean purgeCache, boolean doit,
5782             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5783         int i;
5784         int N;
5785
5786         if (userId == UserHandle.USER_ALL && name == null) {
5787             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5788         }
5789
5790         if (appId < 0 && name != null) {
5791             try {
5792                 appId = UserHandle.getAppId(
5793                         AppGlobals.getPackageManager().getPackageUid(name, 0));
5794             } catch (RemoteException e) {
5795             }
5796         }
5797
5798         if (doit) {
5799             if (name != null) {
5800                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5801                         + " user=" + userId + ": " + reason);
5802             } else {
5803                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5804             }
5805
5806             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5807             for (int ip=pmap.size()-1; ip>=0; ip--) {
5808                 SparseArray<Long> ba = pmap.valueAt(ip);
5809                 for (i=ba.size()-1; i>=0; i--) {
5810                     boolean remove = false;
5811                     final int entUid = ba.keyAt(i);
5812                     if (name != null) {
5813                         if (userId == UserHandle.USER_ALL) {
5814                             if (UserHandle.getAppId(entUid) == appId) {
5815                                 remove = true;
5816                             }
5817                         } else {
5818                             if (entUid == UserHandle.getUid(userId, appId)) {
5819                                 remove = true;
5820                             }
5821                         }
5822                     } else if (UserHandle.getUserId(entUid) == userId) {
5823                         remove = true;
5824                     }
5825                     if (remove) {
5826                         ba.removeAt(i);
5827                     }
5828                 }
5829                 if (ba.size() == 0) {
5830                     pmap.removeAt(ip);
5831                 }
5832             }
5833         }
5834
5835         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5836                 -100, callerWillRestart, true, doit, evenPersistent,
5837                 name == null ? ("stop user " + userId) : ("stop " + name));
5838
5839         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5840             if (!doit) {
5841                 return true;
5842             }
5843             didSomething = true;
5844         }
5845
5846         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5847             if (!doit) {
5848                 return true;
5849             }
5850             didSomething = true;
5851         }
5852
5853         if (name == null) {
5854             // Remove all sticky broadcasts from this user.
5855             mStickyBroadcasts.remove(userId);
5856         }
5857
5858         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5859         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5860                 userId, providers)) {
5861             if (!doit) {
5862                 return true;
5863             }
5864             didSomething = true;
5865         }
5866         N = providers.size();
5867         for (i=0; i<N; i++) {
5868             removeDyingProviderLocked(null, providers.get(i), true);
5869         }
5870
5871         // Remove transient permissions granted from/to this package/user
5872         removeUriPermissionsForPackageLocked(name, userId, false);
5873
5874         if (name == null || uninstalling) {
5875             // Remove pending intents.  For now we only do this when force
5876             // stopping users, because we have some problems when doing this
5877             // for packages -- app widgets are not currently cleaned up for
5878             // such packages, so they can be left with bad pending intents.
5879             if (mIntentSenderRecords.size() > 0) {
5880                 Iterator<WeakReference<PendingIntentRecord>> it
5881                         = mIntentSenderRecords.values().iterator();
5882                 while (it.hasNext()) {
5883                     WeakReference<PendingIntentRecord> wpir = it.next();
5884                     if (wpir == null) {
5885                         it.remove();
5886                         continue;
5887                     }
5888                     PendingIntentRecord pir = wpir.get();
5889                     if (pir == null) {
5890                         it.remove();
5891                         continue;
5892                     }
5893                     if (name == null) {
5894                         // Stopping user, remove all objects for the user.
5895                         if (pir.key.userId != userId) {
5896                             // Not the same user, skip it.
5897                             continue;
5898                         }
5899                     } else {
5900                         if (UserHandle.getAppId(pir.uid) != appId) {
5901                             // Different app id, skip it.
5902                             continue;
5903                         }
5904                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5905                             // Different user, skip it.
5906                             continue;
5907                         }
5908                         if (!pir.key.packageName.equals(name)) {
5909                             // Different package, skip it.
5910                             continue;
5911                         }
5912                     }
5913                     if (!doit) {
5914                         return true;
5915                     }
5916                     didSomething = true;
5917                     it.remove();
5918                     pir.canceled = true;
5919                     if (pir.key.activity != null) {
5920                         pir.key.activity.pendingResults.remove(pir.ref);
5921                     }
5922                 }
5923             }
5924         }
5925
5926         if (doit) {
5927             if (purgeCache && name != null) {
5928                 AttributeCache ac = AttributeCache.instance();
5929                 if (ac != null) {
5930                     ac.removePackage(name);
5931                 }
5932             }
5933             if (mBooted) {
5934                 mStackSupervisor.resumeTopActivitiesLocked();
5935                 mStackSupervisor.scheduleIdleLocked();
5936             }
5937         }
5938
5939         return didSomething;
5940     }
5941
5942     private final boolean removeProcessLocked(ProcessRecord app,
5943             boolean callerWillRestart, boolean allowRestart, String reason) {
5944         final String name = app.processName;
5945         final int uid = app.uid;
5946         if (DEBUG_PROCESSES) Slog.d(
5947             TAG, "Force removing proc " + app.toShortString() + " (" + name
5948             + "/" + uid + ")");
5949
5950         mProcessNames.remove(name, uid);
5951         mIsolatedProcesses.remove(app.uid);
5952         if (mHeavyWeightProcess == app) {
5953             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5954                     mHeavyWeightProcess.userId, 0));
5955             mHeavyWeightProcess = null;
5956         }
5957         boolean needRestart = false;
5958         if (app.pid > 0 && app.pid != MY_PID) {
5959             int pid = app.pid;
5960             synchronized (mPidsSelfLocked) {
5961                 mPidsSelfLocked.remove(pid);
5962                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5963             }
5964             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5965             if (app.isolated) {
5966                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5967             }
5968             app.kill(reason, true);
5969             handleAppDiedLocked(app, true, allowRestart);
5970             removeLruProcessLocked(app);
5971
5972             if (app.persistent && !app.isolated) {
5973                 if (!callerWillRestart) {
5974                     addAppLocked(app.info, false, null /* ABI override */);
5975                 } else {
5976                     needRestart = true;
5977                 }
5978             }
5979         } else {
5980             mRemovedProcesses.add(app);
5981         }
5982
5983         return needRestart;
5984     }
5985
5986     private final void processStartTimedOutLocked(ProcessRecord app) {
5987         final int pid = app.pid;
5988         boolean gone = false;
5989         synchronized (mPidsSelfLocked) {
5990             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5991             if (knownApp != null && knownApp.thread == null) {
5992                 mPidsSelfLocked.remove(pid);
5993                 gone = true;
5994             }
5995         }
5996
5997         if (gone) {
5998             Slog.w(TAG, "Process " + app + " failed to attach");
5999             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6000                     pid, app.uid, app.processName);
6001             mProcessNames.remove(app.processName, app.uid);
6002             mIsolatedProcesses.remove(app.uid);
6003             if (mHeavyWeightProcess == app) {
6004                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6005                         mHeavyWeightProcess.userId, 0));
6006                 mHeavyWeightProcess = null;
6007             }
6008             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6009             if (app.isolated) {
6010                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6011             }
6012             // Take care of any launching providers waiting for this process.
6013             checkAppInLaunchingProvidersLocked(app, true);
6014             // Take care of any services that are waiting for the process.
6015             mServices.processStartTimedOutLocked(app);
6016             app.kill("start timeout", true);
6017             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6018                 Slog.w(TAG, "Unattached app died before backup, skipping");
6019                 try {
6020                     IBackupManager bm = IBackupManager.Stub.asInterface(
6021                             ServiceManager.getService(Context.BACKUP_SERVICE));
6022                     bm.agentDisconnected(app.info.packageName);
6023                 } catch (RemoteException e) {
6024                     // Can't happen; the backup manager is local
6025                 }
6026             }
6027             if (isPendingBroadcastProcessLocked(pid)) {
6028                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6029                 skipPendingBroadcastLocked(pid);
6030             }
6031         } else {
6032             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6033         }
6034     }
6035
6036     private final boolean attachApplicationLocked(IApplicationThread thread,
6037             int pid) {
6038
6039         // Find the application record that is being attached...  either via
6040         // the pid if we are running in multiple processes, or just pull the
6041         // next app record if we are emulating process with anonymous threads.
6042         ProcessRecord app;
6043         if (pid != MY_PID && pid >= 0) {
6044             synchronized (mPidsSelfLocked) {
6045                 app = mPidsSelfLocked.get(pid);
6046             }
6047         } else {
6048             app = null;
6049         }
6050
6051         if (app == null) {
6052             Slog.w(TAG, "No pending application record for pid " + pid
6053                     + " (IApplicationThread " + thread + "); dropping process");
6054             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6055             if (pid > 0 && pid != MY_PID) {
6056                 Process.killProcessQuiet(pid);
6057                 //TODO: Process.killProcessGroup(app.info.uid, pid);
6058             } else {
6059                 try {
6060                     thread.scheduleExit();
6061                 } catch (Exception e) {
6062                     // Ignore exceptions.
6063                 }
6064             }
6065             return false;
6066         }
6067
6068         // If this application record is still attached to a previous
6069         // process, clean it up now.
6070         if (app.thread != null) {
6071             handleAppDiedLocked(app, true, true);
6072         }
6073
6074         // Tell the process all about itself.
6075
6076         if (localLOGV) Slog.v(
6077                 TAG, "Binding process pid " + pid + " to record " + app);
6078
6079         final String processName = app.processName;
6080         try {
6081             AppDeathRecipient adr = new AppDeathRecipient(
6082                     app, pid, thread);
6083             thread.asBinder().linkToDeath(adr, 0);
6084             app.deathRecipient = adr;
6085         } catch (RemoteException e) {
6086             app.resetPackageList(mProcessStats);
6087             startProcessLocked(app, "link fail", processName);
6088             return false;
6089         }
6090
6091         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6092
6093         app.makeActive(thread, mProcessStats);
6094         app.curAdj = app.setAdj = -100;
6095         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6096         app.forcingToForeground = null;
6097         updateProcessForegroundLocked(app, false, false);
6098         app.hasShownUi = false;
6099         app.debugging = false;
6100         app.cached = false;
6101
6102         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6103
6104         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6105         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6106
6107         if (!normalMode) {
6108             Slog.i(TAG, "Launching preboot mode app: " + app);
6109         }
6110
6111         if (localLOGV) Slog.v(
6112             TAG, "New app record " + app
6113             + " thread=" + thread.asBinder() + " pid=" + pid);
6114         try {
6115             int testMode = IApplicationThread.DEBUG_OFF;
6116             if (mDebugApp != null && mDebugApp.equals(processName)) {
6117                 testMode = mWaitForDebugger
6118                     ? IApplicationThread.DEBUG_WAIT
6119                     : IApplicationThread.DEBUG_ON;
6120                 app.debugging = true;
6121                 if (mDebugTransient) {
6122                     mDebugApp = mOrigDebugApp;
6123                     mWaitForDebugger = mOrigWaitForDebugger;
6124                 }
6125             }
6126             String profileFile = app.instrumentationProfileFile;
6127             ParcelFileDescriptor profileFd = null;
6128             int samplingInterval = 0;
6129             boolean profileAutoStop = false;
6130             if (mProfileApp != null && mProfileApp.equals(processName)) {
6131                 mProfileProc = app;
6132                 profileFile = mProfileFile;
6133                 profileFd = mProfileFd;
6134                 samplingInterval = mSamplingInterval;
6135                 profileAutoStop = mAutoStopProfiler;
6136             }
6137             boolean enableOpenGlTrace = false;
6138             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6139                 enableOpenGlTrace = true;
6140                 mOpenGlTraceApp = null;
6141             }
6142
6143             // If the app is being launched for restore or full backup, set it up specially
6144             boolean isRestrictedBackupMode = false;
6145             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6146                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6147                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6148                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6149             }
6150
6151             ensurePackageDexOpt(app.instrumentationInfo != null
6152                     ? app.instrumentationInfo.packageName
6153                     : app.info.packageName);
6154             if (app.instrumentationClass != null) {
6155                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6156             }
6157             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6158                     + processName + " with config " + mConfiguration);
6159             ApplicationInfo appInfo = app.instrumentationInfo != null
6160                     ? app.instrumentationInfo : app.info;
6161             app.compat = compatibilityInfoForPackageLocked(appInfo);
6162             if (profileFd != null) {
6163                 profileFd = profileFd.dup();
6164             }
6165             ProfilerInfo profilerInfo = profileFile == null ? null
6166                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6167             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6168                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6169                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6170                     isRestrictedBackupMode || !normalMode, app.persistent,
6171                     new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6172                     mCoreSettingsObserver.getCoreSettingsLocked());
6173             updateLruProcessLocked(app, false, null);
6174             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6175         } catch (Exception e) {
6176             // todo: Yikes!  What should we do?  For now we will try to
6177             // start another process, but that could easily get us in
6178             // an infinite loop of restarting processes...
6179             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6180
6181             app.resetPackageList(mProcessStats);
6182             app.unlinkDeathRecipient();
6183             startProcessLocked(app, "bind fail", processName);
6184             return false;
6185         }
6186
6187         // Remove this record from the list of starting applications.
6188         mPersistentStartingProcesses.remove(app);
6189         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6190                 "Attach application locked removing on hold: " + app);
6191         mProcessesOnHold.remove(app);
6192
6193         boolean badApp = false;
6194         boolean didSomething = false;
6195
6196         // See if the top visible activity is waiting to run in this process...
6197         if (normalMode) {
6198             try {
6199                 if (mStackSupervisor.attachApplicationLocked(app)) {
6200                     didSomething = true;
6201                 }
6202             } catch (Exception e) {
6203                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6204                 badApp = true;
6205             }
6206         }
6207
6208         // Find any services that should be running in this process...
6209         if (!badApp) {
6210             try {
6211                 didSomething |= mServices.attachApplicationLocked(app, processName);
6212             } catch (Exception e) {
6213                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6214                 badApp = true;
6215             }
6216         }
6217
6218         // Check if a next-broadcast receiver is in this process...
6219         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6220             try {
6221                 didSomething |= sendPendingBroadcastsLocked(app);
6222             } catch (Exception e) {
6223                 // If the app died trying to launch the receiver we declare it 'bad'
6224                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6225                 badApp = true;
6226             }
6227         }
6228
6229         // Check whether the next backup agent is in this process...
6230         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6231             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6232             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6233             try {
6234                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6235                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6236                         mBackupTarget.backupMode);
6237             } catch (Exception e) {
6238                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6239                 badApp = true;
6240             }
6241         }
6242
6243         if (badApp) {
6244             app.kill("error during init", true);
6245             handleAppDiedLocked(app, false, true);
6246             return false;
6247         }
6248
6249         if (!didSomething) {
6250             updateOomAdjLocked();
6251         }
6252
6253         return true;
6254     }
6255
6256     @Override
6257     public final void attachApplication(IApplicationThread thread) {
6258         synchronized (this) {
6259             int callingPid = Binder.getCallingPid();
6260             final long origId = Binder.clearCallingIdentity();
6261             attachApplicationLocked(thread, callingPid);
6262             Binder.restoreCallingIdentity(origId);
6263         }
6264     }
6265
6266     @Override
6267     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6268         final long origId = Binder.clearCallingIdentity();
6269         synchronized (this) {
6270             ActivityStack stack = ActivityRecord.getStackLocked(token);
6271             if (stack != null) {
6272                 ActivityRecord r =
6273                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6274                 if (stopProfiling) {
6275                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6276                         try {
6277                             mProfileFd.close();
6278                         } catch (IOException e) {
6279                         }
6280                         clearProfilerLocked();
6281                     }
6282                 }
6283             }
6284         }
6285         Binder.restoreCallingIdentity(origId);
6286     }
6287
6288     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6289         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6290                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6291     }
6292
6293     void enableScreenAfterBoot() {
6294         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6295                 SystemClock.uptimeMillis());
6296         mWindowManager.enableScreenAfterBoot();
6297
6298         synchronized (this) {
6299             updateEventDispatchingLocked();
6300         }
6301     }
6302
6303     @Override
6304     public void showBootMessage(final CharSequence msg, final boolean always) {
6305         enforceNotIsolatedCaller("showBootMessage");
6306         mWindowManager.showBootMessage(msg, always);
6307     }
6308
6309     @Override
6310     public void keyguardWaitingForActivityDrawn() {
6311         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6312         final long token = Binder.clearCallingIdentity();
6313         try {
6314             synchronized (this) {
6315                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6316                 mWindowManager.keyguardWaitingForActivityDrawn();
6317                 if (mLockScreenShown) {
6318                     mLockScreenShown = false;
6319                     updateSleepIfNeededLocked();
6320                 }
6321             }
6322         } finally {
6323             Binder.restoreCallingIdentity(token);
6324         }
6325     }
6326
6327     final void finishBooting() {
6328         synchronized (this) {
6329             if (!mBootAnimationComplete) {
6330                 mCallFinishBooting = true;
6331                 return;
6332             }
6333             mCallFinishBooting = false;
6334         }
6335
6336         // Register receivers to handle package update events
6337         mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6338
6339         // Let system services know.
6340         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6341
6342         synchronized (this) {
6343             // Ensure that any processes we had put on hold are now started
6344             // up.
6345             final int NP = mProcessesOnHold.size();
6346             if (NP > 0) {
6347                 ArrayList<ProcessRecord> procs =
6348                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6349                 for (int ip=0; ip<NP; ip++) {
6350                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6351                             + procs.get(ip));
6352                     startProcessLocked(procs.get(ip), "on-hold", null);
6353                 }
6354             }
6355             
6356             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6357                 // Start looking for apps that are abusing wake locks.
6358                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6359                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6360                 // Tell anyone interested that we are done booting!
6361                 SystemProperties.set("sys.boot_completed", "1");
6362
6363                 // And trigger dev.bootcomplete if we are not showing encryption progress
6364                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6365                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6366                     SystemProperties.set("dev.bootcomplete", "1");
6367                 }
6368                 for (int i=0; i<mStartedUsers.size(); i++) {
6369                     UserStartedState uss = mStartedUsers.valueAt(i);
6370                     if (uss.mState == UserStartedState.STATE_BOOTING) {
6371                         uss.mState = UserStartedState.STATE_RUNNING;
6372                         final int userId = mStartedUsers.keyAt(i);
6373                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6374                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6375                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6376                         broadcastIntentLocked(null, null, intent, null,
6377                                 new IIntentReceiver.Stub() {
6378                                     @Override
6379                                     public void performReceive(Intent intent, int resultCode,
6380                                             String data, Bundle extras, boolean ordered,
6381                                             boolean sticky, int sendingUser) {
6382                                         synchronized (ActivityManagerService.this) {
6383                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6384                                                     true, false);
6385                                         }
6386                                     }
6387                                 },
6388                                 0, null, null,
6389                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6390                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6391                                 userId);
6392                     }
6393                 }
6394                 scheduleStartProfilesLocked();
6395             }
6396         }
6397     }
6398
6399     @Override
6400     public void bootAnimationComplete() {
6401         final boolean callFinishBooting;
6402         synchronized (this) {
6403             callFinishBooting = mCallFinishBooting;
6404             mBootAnimationComplete = true;
6405         }
6406         if (callFinishBooting) {
6407             finishBooting();
6408         }
6409     }
6410
6411     final void ensureBootCompleted() {
6412         boolean booting;
6413         boolean enableScreen;
6414         synchronized (this) {
6415             booting = mBooting;
6416             mBooting = false;
6417             enableScreen = !mBooted;
6418             mBooted = true;
6419         }
6420
6421         if (booting) {
6422             finishBooting();
6423         }
6424
6425         if (enableScreen) {
6426             enableScreenAfterBoot();
6427         }
6428     }
6429
6430     @Override
6431     public final void activityResumed(IBinder token) {
6432         final long origId = Binder.clearCallingIdentity();
6433         synchronized(this) {
6434             ActivityStack stack = ActivityRecord.getStackLocked(token);
6435             if (stack != null) {
6436                 ActivityRecord.activityResumedLocked(token);
6437             }
6438         }
6439         Binder.restoreCallingIdentity(origId);
6440     }
6441
6442     @Override
6443     public final void activityPaused(IBinder token) {
6444         final long origId = Binder.clearCallingIdentity();
6445         synchronized(this) {
6446             ActivityStack stack = ActivityRecord.getStackLocked(token);
6447             if (stack != null) {
6448                 stack.activityPausedLocked(token, false);
6449             }
6450         }
6451         Binder.restoreCallingIdentity(origId);
6452     }
6453
6454     @Override
6455     public final void activityStopped(IBinder token, Bundle icicle,
6456             PersistableBundle persistentState, CharSequence description) {
6457         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6458
6459         // Refuse possible leaked file descriptors
6460         if (icicle != null && icicle.hasFileDescriptors()) {
6461             throw new IllegalArgumentException("File descriptors passed in Bundle");
6462         }
6463
6464         final long origId = Binder.clearCallingIdentity();
6465
6466         synchronized (this) {
6467             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6468             if (r != null) {
6469                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6470             }
6471         }
6472
6473         trimApplications();
6474
6475         Binder.restoreCallingIdentity(origId);
6476     }
6477
6478     @Override
6479     public final void activityDestroyed(IBinder token) {
6480         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6481         synchronized (this) {
6482             ActivityStack stack = ActivityRecord.getStackLocked(token);
6483             if (stack != null) {
6484                 stack.activityDestroyedLocked(token);
6485             }
6486         }
6487     }
6488
6489     @Override
6490     public final void backgroundResourcesReleased(IBinder token) {
6491         final long origId = Binder.clearCallingIdentity();
6492         try {
6493             synchronized (this) {
6494                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6495                 if (stack != null) {
6496                     stack.backgroundResourcesReleased(token);
6497                 }
6498             }
6499         } finally {
6500             Binder.restoreCallingIdentity(origId);
6501         }
6502     }
6503
6504     @Override
6505     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6506         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6507     }
6508
6509     @Override
6510     public final void notifyEnterAnimationComplete(IBinder token) {
6511         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6512     }
6513
6514     @Override
6515     public String getCallingPackage(IBinder token) {
6516         synchronized (this) {
6517             ActivityRecord r = getCallingRecordLocked(token);
6518             return r != null ? r.info.packageName : null;
6519         }
6520     }
6521
6522     @Override
6523     public ComponentName getCallingActivity(IBinder token) {
6524         synchronized (this) {
6525             ActivityRecord r = getCallingRecordLocked(token);
6526             return r != null ? r.intent.getComponent() : null;
6527         }
6528     }
6529
6530     private ActivityRecord getCallingRecordLocked(IBinder token) {
6531         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6532         if (r == null) {
6533             return null;
6534         }
6535         return r.resultTo;
6536     }
6537
6538     @Override
6539     public ComponentName getActivityClassForToken(IBinder token) {
6540         synchronized(this) {
6541             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6542             if (r == null) {
6543                 return null;
6544             }
6545             return r.intent.getComponent();
6546         }
6547     }
6548
6549     @Override
6550     public String getPackageForToken(IBinder token) {
6551         synchronized(this) {
6552             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6553             if (r == null) {
6554                 return null;
6555             }
6556             return r.packageName;
6557         }
6558     }
6559
6560     @Override
6561     public IIntentSender getIntentSender(int type,
6562             String packageName, IBinder token, String resultWho,
6563             int requestCode, Intent[] intents, String[] resolvedTypes,
6564             int flags, Bundle options, int userId) {
6565         enforceNotIsolatedCaller("getIntentSender");
6566         // Refuse possible leaked file descriptors
6567         if (intents != null) {
6568             if (intents.length < 1) {
6569                 throw new IllegalArgumentException("Intents array length must be >= 1");
6570             }
6571             for (int i=0; i<intents.length; i++) {
6572                 Intent intent = intents[i];
6573                 if (intent != null) {
6574                     if (intent.hasFileDescriptors()) {
6575                         throw new IllegalArgumentException("File descriptors passed in Intent");
6576                     }
6577                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6578                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6579                         throw new IllegalArgumentException(
6580                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6581                     }
6582                     intents[i] = new Intent(intent);
6583                 }
6584             }
6585             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6586                 throw new IllegalArgumentException(
6587                         "Intent array length does not match resolvedTypes length");
6588             }
6589         }
6590         if (options != null) {
6591             if (options.hasFileDescriptors()) {
6592                 throw new IllegalArgumentException("File descriptors passed in options");
6593             }
6594         }
6595         
6596         synchronized(this) {
6597             int callingUid = Binder.getCallingUid();
6598             int origUserId = userId;
6599             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6600                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6601                     ALLOW_NON_FULL, "getIntentSender", null);
6602             if (origUserId == UserHandle.USER_CURRENT) {
6603                 // We don't want to evaluate this until the pending intent is
6604                 // actually executed.  However, we do want to always do the
6605                 // security checking for it above.
6606                 userId = UserHandle.USER_CURRENT;
6607             }
6608             try {
6609                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6610                     int uid = AppGlobals.getPackageManager()
6611                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6612                     if (!UserHandle.isSameApp(callingUid, uid)) {
6613                         String msg = "Permission Denial: getIntentSender() from pid="
6614                             + Binder.getCallingPid()
6615                             + ", uid=" + Binder.getCallingUid()
6616                             + ", (need uid=" + uid + ")"
6617                             + " is not allowed to send as package " + packageName;
6618                         Slog.w(TAG, msg);
6619                         throw new SecurityException(msg);
6620                     }
6621                 }
6622
6623                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6624                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6625                 
6626             } catch (RemoteException e) {
6627                 throw new SecurityException(e);
6628             }
6629         }
6630     }
6631
6632     IIntentSender getIntentSenderLocked(int type, String packageName,
6633             int callingUid, int userId, IBinder token, String resultWho,
6634             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6635             Bundle options) {
6636         if (DEBUG_MU)
6637             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6638         ActivityRecord activity = null;
6639         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6640             activity = ActivityRecord.isInStackLocked(token);
6641             if (activity == null) {
6642                 return null;
6643             }
6644             if (activity.finishing) {
6645                 return null;
6646             }
6647         }
6648
6649         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6650         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6651         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6652         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6653                 |PendingIntent.FLAG_UPDATE_CURRENT);
6654
6655         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6656                 type, packageName, activity, resultWho,
6657                 requestCode, intents, resolvedTypes, flags, options, userId);
6658         WeakReference<PendingIntentRecord> ref;
6659         ref = mIntentSenderRecords.get(key);
6660         PendingIntentRecord rec = ref != null ? ref.get() : null;
6661         if (rec != null) {
6662             if (!cancelCurrent) {
6663                 if (updateCurrent) {
6664                     if (rec.key.requestIntent != null) {
6665                         rec.key.requestIntent.replaceExtras(intents != null ?
6666                                 intents[intents.length - 1] : null);
6667                     }
6668                     if (intents != null) {
6669                         intents[intents.length-1] = rec.key.requestIntent;
6670                         rec.key.allIntents = intents;
6671                         rec.key.allResolvedTypes = resolvedTypes;
6672                     } else {
6673                         rec.key.allIntents = null;
6674                         rec.key.allResolvedTypes = null;
6675                     }
6676                 }
6677                 return rec;
6678             }
6679             rec.canceled = true;
6680             mIntentSenderRecords.remove(key);
6681         }
6682         if (noCreate) {
6683             return rec;
6684         }
6685         rec = new PendingIntentRecord(this, key, callingUid);
6686         mIntentSenderRecords.put(key, rec.ref);
6687         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6688             if (activity.pendingResults == null) {
6689                 activity.pendingResults
6690                         = new HashSet<WeakReference<PendingIntentRecord>>();
6691             }
6692             activity.pendingResults.add(rec.ref);
6693         }
6694         return rec;
6695     }
6696
6697     @Override
6698     public void cancelIntentSender(IIntentSender sender) {
6699         if (!(sender instanceof PendingIntentRecord)) {
6700             return;
6701         }
6702         synchronized(this) {
6703             PendingIntentRecord rec = (PendingIntentRecord)sender;
6704             try {
6705                 int uid = AppGlobals.getPackageManager()
6706                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6707                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6708                     String msg = "Permission Denial: cancelIntentSender() from pid="
6709                         + Binder.getCallingPid()
6710                         + ", uid=" + Binder.getCallingUid()
6711                         + " is not allowed to cancel packges "
6712                         + rec.key.packageName;
6713                     Slog.w(TAG, msg);
6714                     throw new SecurityException(msg);
6715                 }
6716             } catch (RemoteException e) {
6717                 throw new SecurityException(e);
6718             }
6719             cancelIntentSenderLocked(rec, true);
6720         }
6721     }
6722
6723     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6724         rec.canceled = true;
6725         mIntentSenderRecords.remove(rec.key);
6726         if (cleanActivity && rec.key.activity != null) {
6727             rec.key.activity.pendingResults.remove(rec.ref);
6728         }
6729     }
6730
6731     @Override
6732     public String getPackageForIntentSender(IIntentSender pendingResult) {
6733         if (!(pendingResult instanceof PendingIntentRecord)) {
6734             return null;
6735         }
6736         try {
6737             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6738             return res.key.packageName;
6739         } catch (ClassCastException e) {
6740         }
6741         return null;
6742     }
6743
6744     @Override
6745     public int getUidForIntentSender(IIntentSender sender) {
6746         if (sender instanceof PendingIntentRecord) {
6747             try {
6748                 PendingIntentRecord res = (PendingIntentRecord)sender;
6749                 return res.uid;
6750             } catch (ClassCastException e) {
6751             }
6752         }
6753         return -1;
6754     }
6755
6756     @Override
6757     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6758         if (!(pendingResult instanceof PendingIntentRecord)) {
6759             return false;
6760         }
6761         try {
6762             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6763             if (res.key.allIntents == null) {
6764                 return false;
6765             }
6766             for (int i=0; i<res.key.allIntents.length; i++) {
6767                 Intent intent = res.key.allIntents[i];
6768                 if (intent.getPackage() != null && intent.getComponent() != null) {
6769                     return false;
6770                 }
6771             }
6772             return true;
6773         } catch (ClassCastException e) {
6774         }
6775         return false;
6776     }
6777
6778     @Override
6779     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6780         if (!(pendingResult instanceof PendingIntentRecord)) {
6781             return false;
6782         }
6783         try {
6784             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6785             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6786                 return true;
6787             }
6788             return false;
6789         } catch (ClassCastException e) {
6790         }
6791         return false;
6792     }
6793
6794     @Override
6795     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6796         if (!(pendingResult instanceof PendingIntentRecord)) {
6797             return null;
6798         }
6799         try {
6800             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6801             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6802         } catch (ClassCastException e) {
6803         }
6804         return null;
6805     }
6806
6807     @Override
6808     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6809         if (!(pendingResult instanceof PendingIntentRecord)) {
6810             return null;
6811         }
6812         try {
6813             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6814             Intent intent = res.key.requestIntent;
6815             if (intent != null) {
6816                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6817                         || res.lastTagPrefix.equals(prefix))) {
6818                     return res.lastTag;
6819                 }
6820                 res.lastTagPrefix = prefix;
6821                 StringBuilder sb = new StringBuilder(128);
6822                 if (prefix != null) {
6823                     sb.append(prefix);
6824                 }
6825                 if (intent.getAction() != null) {
6826                     sb.append(intent.getAction());
6827                 } else if (intent.getComponent() != null) {
6828                     intent.getComponent().appendShortString(sb);
6829                 } else {
6830                     sb.append("?");
6831                 }
6832                 return res.lastTag = sb.toString();
6833             }
6834         } catch (ClassCastException e) {
6835         }
6836         return null;
6837     }
6838
6839     @Override
6840     public void setProcessLimit(int max) {
6841         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6842                 "setProcessLimit()");
6843         synchronized (this) {
6844             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6845             mProcessLimitOverride = max;
6846         }
6847         trimApplications();
6848     }
6849
6850     @Override
6851     public int getProcessLimit() {
6852         synchronized (this) {
6853             return mProcessLimitOverride;
6854         }
6855     }
6856
6857     void foregroundTokenDied(ForegroundToken token) {
6858         synchronized (ActivityManagerService.this) {
6859             synchronized (mPidsSelfLocked) {
6860                 ForegroundToken cur
6861                     = mForegroundProcesses.get(token.pid);
6862                 if (cur != token) {
6863                     return;
6864                 }
6865                 mForegroundProcesses.remove(token.pid);
6866                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6867                 if (pr == null) {
6868                     return;
6869                 }
6870                 pr.forcingToForeground = null;
6871                 updateProcessForegroundLocked(pr, false, false);
6872             }
6873             updateOomAdjLocked();
6874         }
6875     }
6876
6877     @Override
6878     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6879         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6880                 "setProcessForeground()");
6881         synchronized(this) {
6882             boolean changed = false;
6883             
6884             synchronized (mPidsSelfLocked) {
6885                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6886                 if (pr == null && isForeground) {
6887                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6888                     return;
6889                 }
6890                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6891                 if (oldToken != null) {
6892                     oldToken.token.unlinkToDeath(oldToken, 0);
6893                     mForegroundProcesses.remove(pid);
6894                     if (pr != null) {
6895                         pr.forcingToForeground = null;
6896                     }
6897                     changed = true;
6898                 }
6899                 if (isForeground && token != null) {
6900                     ForegroundToken newToken = new ForegroundToken() {
6901                         @Override
6902                         public void binderDied() {
6903                             foregroundTokenDied(this);
6904                         }
6905                     };
6906                     newToken.pid = pid;
6907                     newToken.token = token;
6908                     try {
6909                         token.linkToDeath(newToken, 0);
6910                         mForegroundProcesses.put(pid, newToken);
6911                         pr.forcingToForeground = token;
6912                         changed = true;
6913                     } catch (RemoteException e) {
6914                         // If the process died while doing this, we will later
6915                         // do the cleanup with the process death link.
6916                     }
6917                 }
6918             }
6919             
6920             if (changed) {
6921                 updateOomAdjLocked();
6922             }
6923         }
6924     }
6925     
6926     // =========================================================
6927     // PERMISSIONS
6928     // =========================================================
6929
6930     static class PermissionController extends IPermissionController.Stub {
6931         ActivityManagerService mActivityManagerService;
6932         PermissionController(ActivityManagerService activityManagerService) {
6933             mActivityManagerService = activityManagerService;
6934         }
6935
6936         @Override
6937         public boolean checkPermission(String permission, int pid, int uid) {
6938             return mActivityManagerService.checkPermission(permission, pid,
6939                     uid) == PackageManager.PERMISSION_GRANTED;
6940         }
6941     }
6942
6943     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6944         @Override
6945         public int checkComponentPermission(String permission, int pid, int uid,
6946                 int owningUid, boolean exported) {
6947             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6948                     owningUid, exported);
6949         }
6950
6951         @Override
6952         public Object getAMSLock() {
6953             return ActivityManagerService.this;
6954         }
6955     }
6956
6957     /**
6958      * This can be called with or without the global lock held.
6959      */
6960     int checkComponentPermission(String permission, int pid, int uid,
6961             int owningUid, boolean exported) {
6962         // We might be performing an operation on behalf of an indirect binder
6963         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6964         // client identity accordingly before proceeding.
6965         Identity tlsIdentity = sCallerIdentity.get();
6966         if (tlsIdentity != null) {
6967             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6968                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6969             uid = tlsIdentity.uid;
6970             pid = tlsIdentity.pid;
6971         }
6972
6973         if (pid == MY_PID) {
6974             return PackageManager.PERMISSION_GRANTED;
6975         }
6976
6977         return ActivityManager.checkComponentPermission(permission, uid,
6978                 owningUid, exported);
6979     }
6980
6981     /**
6982      * As the only public entry point for permissions checking, this method
6983      * can enforce the semantic that requesting a check on a null global
6984      * permission is automatically denied.  (Internally a null permission
6985      * string is used when calling {@link #checkComponentPermission} in cases
6986      * when only uid-based security is needed.)
6987      * 
6988      * This can be called with or without the global lock held.
6989      */
6990     @Override
6991     public int checkPermission(String permission, int pid, int uid) {
6992         if (permission == null) {
6993             return PackageManager.PERMISSION_DENIED;
6994         }
6995         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6996     }
6997
6998     /**
6999      * Binder IPC calls go through the public entry point.
7000      * This can be called with or without the global lock held.
7001      */
7002     int checkCallingPermission(String permission) {
7003         return checkPermission(permission,
7004                 Binder.getCallingPid(),
7005                 UserHandle.getAppId(Binder.getCallingUid()));
7006     }
7007
7008     /**
7009      * This can be called with or without the global lock held.
7010      */
7011     void enforceCallingPermission(String permission, String func) {
7012         if (checkCallingPermission(permission)
7013                 == PackageManager.PERMISSION_GRANTED) {
7014             return;
7015         }
7016
7017         String msg = "Permission Denial: " + func + " from pid="
7018                 + Binder.getCallingPid()
7019                 + ", uid=" + Binder.getCallingUid()
7020                 + " requires " + permission;
7021         Slog.w(TAG, msg);
7022         throw new SecurityException(msg);
7023     }
7024
7025     /**
7026      * Determine if UID is holding permissions required to access {@link Uri} in
7027      * the given {@link ProviderInfo}. Final permission checking is always done
7028      * in {@link ContentProvider}.
7029      */
7030     private final boolean checkHoldingPermissionsLocked(
7031             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7032         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7033                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7034         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7035             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7036                     != PERMISSION_GRANTED) {
7037                 return false;
7038             }
7039         }
7040         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7041     }
7042
7043     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7044             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7045         if (pi.applicationInfo.uid == uid) {
7046             return true;
7047         } else if (!pi.exported) {
7048             return false;
7049         }
7050
7051         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7052         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7053         try {
7054             // check if target holds top-level <provider> permissions
7055             if (!readMet && pi.readPermission != null && considerUidPermissions
7056                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7057                 readMet = true;
7058             }
7059             if (!writeMet && pi.writePermission != null && considerUidPermissions
7060                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7061                 writeMet = true;
7062             }
7063
7064             // track if unprotected read/write is allowed; any denied
7065             // <path-permission> below removes this ability
7066             boolean allowDefaultRead = pi.readPermission == null;
7067             boolean allowDefaultWrite = pi.writePermission == null;
7068
7069             // check if target holds any <path-permission> that match uri
7070             final PathPermission[] pps = pi.pathPermissions;
7071             if (pps != null) {
7072                 final String path = grantUri.uri.getPath();
7073                 int i = pps.length;
7074                 while (i > 0 && (!readMet || !writeMet)) {
7075                     i--;
7076                     PathPermission pp = pps[i];
7077                     if (pp.match(path)) {
7078                         if (!readMet) {
7079                             final String pprperm = pp.getReadPermission();
7080                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7081                                     + pprperm + " for " + pp.getPath()
7082                                     + ": match=" + pp.match(path)
7083                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7084                             if (pprperm != null) {
7085                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7086                                         == PERMISSION_GRANTED) {
7087                                     readMet = true;
7088                                 } else {
7089                                     allowDefaultRead = false;
7090                                 }
7091                             }
7092                         }
7093                         if (!writeMet) {
7094                             final String ppwperm = pp.getWritePermission();
7095                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7096                                     + ppwperm + " for " + pp.getPath()
7097                                     + ": match=" + pp.match(path)
7098                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7099                             if (ppwperm != null) {
7100                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7101                                         == PERMISSION_GRANTED) {
7102                                     writeMet = true;
7103                                 } else {
7104                                     allowDefaultWrite = false;
7105                                 }
7106                             }
7107                         }
7108                     }
7109                 }
7110             }
7111
7112             // grant unprotected <provider> read/write, if not blocked by
7113             // <path-permission> above
7114             if (allowDefaultRead) readMet = true;
7115             if (allowDefaultWrite) writeMet = true;
7116
7117         } catch (RemoteException e) {
7118             return false;
7119         }
7120
7121         return readMet && writeMet;
7122     }
7123
7124     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7125         ProviderInfo pi = null;
7126         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7127         if (cpr != null) {
7128             pi = cpr.info;
7129         } else {
7130             try {
7131                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7132                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7133             } catch (RemoteException ex) {
7134             }
7135         }
7136         return pi;
7137     }
7138
7139     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7140         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7141         if (targetUris != null) {
7142             return targetUris.get(grantUri);
7143         }
7144         return null;
7145     }
7146
7147     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7148             String targetPkg, int targetUid, GrantUri grantUri) {
7149         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7150         if (targetUris == null) {
7151             targetUris = Maps.newArrayMap();
7152             mGrantedUriPermissions.put(targetUid, targetUris);
7153         }
7154
7155         UriPermission perm = targetUris.get(grantUri);
7156         if (perm == null) {
7157             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7158             targetUris.put(grantUri, perm);
7159         }
7160
7161         return perm;
7162     }
7163
7164     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7165             final int modeFlags) {
7166         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7167         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7168                 : UriPermission.STRENGTH_OWNED;
7169
7170         // Root gets to do everything.
7171         if (uid == 0) {
7172             return true;
7173         }
7174
7175         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7176         if (perms == null) return false;
7177
7178         // First look for exact match
7179         final UriPermission exactPerm = perms.get(grantUri);
7180         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7181             return true;
7182         }
7183
7184         // No exact match, look for prefixes
7185         final int N = perms.size();
7186         for (int i = 0; i < N; i++) {
7187             final UriPermission perm = perms.valueAt(i);
7188             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7189                     && perm.getStrength(modeFlags) >= minStrength) {
7190                 return true;
7191             }
7192         }
7193
7194         return false;
7195     }
7196
7197     /**
7198      * @param uri This uri must NOT contain an embedded userId.
7199      * @param userId The userId in which the uri is to be resolved.
7200      */
7201     @Override
7202     public int checkUriPermission(Uri uri, int pid, int uid,
7203             final int modeFlags, int userId) {
7204         enforceNotIsolatedCaller("checkUriPermission");
7205
7206         // Another redirected-binder-call permissions check as in
7207         // {@link checkComponentPermission}.
7208         Identity tlsIdentity = sCallerIdentity.get();
7209         if (tlsIdentity != null) {
7210             uid = tlsIdentity.uid;
7211             pid = tlsIdentity.pid;
7212         }
7213
7214         // Our own process gets to do everything.
7215         if (pid == MY_PID) {
7216             return PackageManager.PERMISSION_GRANTED;
7217         }
7218         synchronized (this) {
7219             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7220                     ? PackageManager.PERMISSION_GRANTED
7221                     : PackageManager.PERMISSION_DENIED;
7222         }
7223     }
7224
7225     /**
7226      * Check if the targetPkg can be granted permission to access uri by
7227      * the callingUid using the given modeFlags.  Throws a security exception
7228      * if callingUid is not allowed to do this.  Returns the uid of the target
7229      * if the URI permission grant should be performed; returns -1 if it is not
7230      * needed (for example targetPkg already has permission to access the URI).
7231      * If you already know the uid of the target, you can supply it in
7232      * lastTargetUid else set that to -1.
7233      */
7234     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7235             final int modeFlags, int lastTargetUid) {
7236         if (!Intent.isAccessUriMode(modeFlags)) {
7237             return -1;
7238         }
7239
7240         if (targetPkg != null) {
7241             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7242                     "Checking grant " + targetPkg + " permission to " + grantUri);
7243         }
7244         
7245         final IPackageManager pm = AppGlobals.getPackageManager();
7246
7247         // If this is not a content: uri, we can't do anything with it.
7248         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7249             if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7250                     "Can't grant URI permission for non-content URI: " + grantUri);
7251             return -1;
7252         }
7253
7254         final String authority = grantUri.uri.getAuthority();
7255         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7256         if (pi == null) {
7257             Slog.w(TAG, "No content provider found for permission check: " +
7258                     grantUri.uri.toSafeString());
7259             return -1;
7260         }
7261
7262         int targetUid = lastTargetUid;
7263         if (targetUid < 0 && targetPkg != null) {
7264             try {
7265                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7266                 if (targetUid < 0) {
7267                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7268                             "Can't grant URI permission no uid for: " + targetPkg);
7269                     return -1;
7270                 }
7271             } catch (RemoteException ex) {
7272                 return -1;
7273             }
7274         }
7275
7276         if (targetUid >= 0) {
7277             // First...  does the target actually need this permission?
7278             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7279                 // No need to grant the target this permission.
7280                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7281                         "Target " + targetPkg + " already has full permission to " + grantUri);
7282                 return -1;
7283             }
7284         } else {
7285             // First...  there is no target package, so can anyone access it?
7286             boolean allowed = pi.exported;
7287             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7288                 if (pi.readPermission != null) {
7289                     allowed = false;
7290                 }
7291             }
7292             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7293                 if (pi.writePermission != null) {
7294                     allowed = false;
7295                 }
7296             }
7297             if (allowed) {
7298                 return -1;
7299             }
7300         }
7301
7302         /* There is a special cross user grant if:
7303          * - The target is on another user.
7304          * - Apps on the current user can access the uri without any uid permissions.
7305          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7306          * grant uri permissions.
7307          */
7308         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7309                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7310                 modeFlags, false /*without considering the uid permissions*/);
7311
7312         // Second...  is the provider allowing granting of URI permissions?
7313         if (!specialCrossUserGrant) {
7314             if (!pi.grantUriPermissions) {
7315                 throw new SecurityException("Provider " + pi.packageName
7316                         + "/" + pi.name
7317                         + " does not allow granting of Uri permissions (uri "
7318                         + grantUri + ")");
7319             }
7320             if (pi.uriPermissionPatterns != null) {
7321                 final int N = pi.uriPermissionPatterns.length;
7322                 boolean allowed = false;
7323                 for (int i=0; i<N; i++) {
7324                     if (pi.uriPermissionPatterns[i] != null
7325                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7326                         allowed = true;
7327                         break;
7328                     }
7329                 }
7330                 if (!allowed) {
7331                     throw new SecurityException("Provider " + pi.packageName
7332                             + "/" + pi.name
7333                             + " does not allow granting of permission to path of Uri "
7334                             + grantUri);
7335                 }
7336             }
7337         }
7338
7339         // Third...  does the caller itself have permission to access
7340         // this uri?
7341         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7342             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7343                 // Require they hold a strong enough Uri permission
7344                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7345                     throw new SecurityException("Uid " + callingUid
7346                             + " does not have permission to uri " + grantUri);
7347                 }
7348             }
7349         }
7350         return targetUid;
7351     }
7352
7353     /**
7354      * @param uri This uri must NOT contain an embedded userId.
7355      * @param userId The userId in which the uri is to be resolved.
7356      */
7357     @Override
7358     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7359             final int modeFlags, int userId) {
7360         enforceNotIsolatedCaller("checkGrantUriPermission");
7361         synchronized(this) {
7362             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7363                     new GrantUri(userId, uri, false), modeFlags, -1);
7364         }
7365     }
7366
7367     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7368             final int modeFlags, UriPermissionOwner owner) {
7369         if (!Intent.isAccessUriMode(modeFlags)) {
7370             return;
7371         }
7372
7373         // So here we are: the caller has the assumed permission
7374         // to the uri, and the target doesn't.  Let's now give this to
7375         // the target.
7376
7377         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7378                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7379
7380         final String authority = grantUri.uri.getAuthority();
7381         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7382         if (pi == null) {
7383             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7384             return;
7385         }
7386
7387         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7388             grantUri.prefix = true;
7389         }
7390         final UriPermission perm = findOrCreateUriPermissionLocked(
7391                 pi.packageName, targetPkg, targetUid, grantUri);
7392         perm.grantModes(modeFlags, owner);
7393     }
7394
7395     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7396             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7397         if (targetPkg == null) {
7398             throw new NullPointerException("targetPkg");
7399         }
7400         int targetUid;
7401         final IPackageManager pm = AppGlobals.getPackageManager();
7402         try {
7403             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7404         } catch (RemoteException ex) {
7405             return;
7406         }
7407
7408         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7409                 targetUid);
7410         if (targetUid < 0) {
7411             return;
7412         }
7413
7414         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7415                 owner);
7416     }
7417
7418     static class NeededUriGrants extends ArrayList<GrantUri> {
7419         final String targetPkg;
7420         final int targetUid;
7421         final int flags;
7422
7423         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7424             this.targetPkg = targetPkg;
7425             this.targetUid = targetUid;
7426             this.flags = flags;
7427         }
7428     }
7429
7430     /**
7431      * Like checkGrantUriPermissionLocked, but takes an Intent.
7432      */
7433     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7434             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7435         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7436                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7437                 + " clip=" + (intent != null ? intent.getClipData() : null)
7438                 + " from " + intent + "; flags=0x"
7439                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7440
7441         if (targetPkg == null) {
7442             throw new NullPointerException("targetPkg");
7443         }
7444
7445         if (intent == null) {
7446             return null;
7447         }
7448         Uri data = intent.getData();
7449         ClipData clip = intent.getClipData();
7450         if (data == null && clip == null) {
7451             return null;
7452         }
7453         // Default userId for uris in the intent (if they don't specify it themselves)
7454         int contentUserHint = intent.getContentUserHint();
7455         if (contentUserHint == UserHandle.USER_CURRENT) {
7456             contentUserHint = UserHandle.getUserId(callingUid);
7457         }
7458         final IPackageManager pm = AppGlobals.getPackageManager();
7459         int targetUid;
7460         if (needed != null) {
7461             targetUid = needed.targetUid;
7462         } else {
7463             try {
7464                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7465             } catch (RemoteException ex) {
7466                 return null;
7467             }
7468             if (targetUid < 0) {
7469                 if (DEBUG_URI_PERMISSION) {
7470                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7471                             + " on user " + targetUserId);
7472                 }
7473                 return null;
7474             }
7475         }
7476         if (data != null) {
7477             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7478             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7479                     targetUid);
7480             if (targetUid > 0) {
7481                 if (needed == null) {
7482                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7483                 }
7484                 needed.add(grantUri);
7485             }
7486         }
7487         if (clip != null) {
7488             for (int i=0; i<clip.getItemCount(); i++) {
7489                 Uri uri = clip.getItemAt(i).getUri();
7490                 if (uri != null) {
7491                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7492                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7493                             targetUid);
7494                     if (targetUid > 0) {
7495                         if (needed == null) {
7496                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7497                         }
7498                         needed.add(grantUri);
7499                     }
7500                 } else {
7501                     Intent clipIntent = clip.getItemAt(i).getIntent();
7502                     if (clipIntent != null) {
7503                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7504                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7505                         if (newNeeded != null) {
7506                             needed = newNeeded;
7507                         }
7508                     }
7509                 }
7510             }
7511         }
7512
7513         return needed;
7514     }
7515
7516     /**
7517      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7518      */
7519     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7520             UriPermissionOwner owner) {
7521         if (needed != null) {
7522             for (int i=0; i<needed.size(); i++) {
7523                 GrantUri grantUri = needed.get(i);
7524                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7525                         grantUri, needed.flags, owner);
7526             }
7527         }
7528     }
7529
7530     void grantUriPermissionFromIntentLocked(int callingUid,
7531             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7532         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7533                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7534         if (needed == null) {
7535             return;
7536         }
7537
7538         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7539     }
7540
7541     /**
7542      * @param uri This uri must NOT contain an embedded userId.
7543      * @param userId The userId in which the uri is to be resolved.
7544      */
7545     @Override
7546     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7547             final int modeFlags, int userId) {
7548         enforceNotIsolatedCaller("grantUriPermission");
7549         GrantUri grantUri = new GrantUri(userId, uri, false);
7550         synchronized(this) {
7551             final ProcessRecord r = getRecordForAppLocked(caller);
7552             if (r == null) {
7553                 throw new SecurityException("Unable to find app for caller "
7554                         + caller
7555                         + " when granting permission to uri " + grantUri);
7556             }
7557             if (targetPkg == null) {
7558                 throw new IllegalArgumentException("null target");
7559             }
7560             if (grantUri == null) {
7561                 throw new IllegalArgumentException("null uri");
7562             }
7563
7564             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7565                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7566                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7567                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7568
7569             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7570                     UserHandle.getUserId(r.uid));
7571         }
7572     }
7573
7574     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7575         if (perm.modeFlags == 0) {
7576             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7577                     perm.targetUid);
7578             if (perms != null) {
7579                 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7580                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7581
7582                 perms.remove(perm.uri);
7583                 if (perms.isEmpty()) {
7584                     mGrantedUriPermissions.remove(perm.targetUid);
7585                 }
7586             }
7587         }
7588     }
7589
7590     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7591         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7592
7593         final IPackageManager pm = AppGlobals.getPackageManager();
7594         final String authority = grantUri.uri.getAuthority();
7595         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7596         if (pi == null) {
7597             Slog.w(TAG, "No content provider found for permission revoke: "
7598                     + grantUri.toSafeString());
7599             return;
7600         }
7601
7602         // Does the caller have this permission on the URI?
7603         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7604             // If they don't have direct access to the URI, then revoke any
7605             // ownerless URI permissions that have been granted to them.
7606             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7607             if (perms != null) {
7608                 boolean persistChanged = false;
7609                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7610                     final UriPermission perm = it.next();
7611                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7612                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7613                         if (DEBUG_URI_PERMISSION)
7614                             Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7615                                     " permission to " + perm.uri);
7616                         persistChanged |= perm.revokeModes(
7617                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7618                         if (perm.modeFlags == 0) {
7619                             it.remove();
7620                         }
7621                     }
7622                 }
7623                 if (perms.isEmpty()) {
7624                     mGrantedUriPermissions.remove(callingUid);
7625                 }
7626                 if (persistChanged) {
7627                     schedulePersistUriGrants();
7628                 }
7629             }
7630             return;
7631         }
7632
7633         boolean persistChanged = false;
7634
7635         // Go through all of the permissions and remove any that match.
7636         int N = mGrantedUriPermissions.size();
7637         for (int i = 0; i < N; i++) {
7638             final int targetUid = mGrantedUriPermissions.keyAt(i);
7639             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7640
7641             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7642                 final UriPermission perm = it.next();
7643                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7644                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7645                     if (DEBUG_URI_PERMISSION)
7646                         Slog.v(TAG,
7647                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7648                     persistChanged |= perm.revokeModes(
7649                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7650                     if (perm.modeFlags == 0) {
7651                         it.remove();
7652                     }
7653                 }
7654             }
7655
7656             if (perms.isEmpty()) {
7657                 mGrantedUriPermissions.remove(targetUid);
7658                 N--;
7659                 i--;
7660             }
7661         }
7662
7663         if (persistChanged) {
7664             schedulePersistUriGrants();
7665         }
7666     }
7667
7668     /**
7669      * @param uri This uri must NOT contain an embedded userId.
7670      * @param userId The userId in which the uri is to be resolved.
7671      */
7672     @Override
7673     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7674             int userId) {
7675         enforceNotIsolatedCaller("revokeUriPermission");
7676         synchronized(this) {
7677             final ProcessRecord r = getRecordForAppLocked(caller);
7678             if (r == null) {
7679                 throw new SecurityException("Unable to find app for caller "
7680                         + caller
7681                         + " when revoking permission to uri " + uri);
7682             }
7683             if (uri == null) {
7684                 Slog.w(TAG, "revokeUriPermission: null uri");
7685                 return;
7686             }
7687
7688             if (!Intent.isAccessUriMode(modeFlags)) {
7689                 return;
7690             }
7691
7692             final IPackageManager pm = AppGlobals.getPackageManager();
7693             final String authority = uri.getAuthority();
7694             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7695             if (pi == null) {
7696                 Slog.w(TAG, "No content provider found for permission revoke: "
7697                         + uri.toSafeString());
7698                 return;
7699             }
7700
7701             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7702         }
7703     }
7704
7705     /**
7706      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7707      * given package.
7708      *
7709      * @param packageName Package name to match, or {@code null} to apply to all
7710      *            packages.
7711      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7712      *            to all users.
7713      * @param persistable If persistable grants should be removed.
7714      */
7715     private void removeUriPermissionsForPackageLocked(
7716             String packageName, int userHandle, boolean persistable) {
7717         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7718             throw new IllegalArgumentException("Must narrow by either package or user");
7719         }
7720
7721         boolean persistChanged = false;
7722
7723         int N = mGrantedUriPermissions.size();
7724         for (int i = 0; i < N; i++) {
7725             final int targetUid = mGrantedUriPermissions.keyAt(i);
7726             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7727
7728             // Only inspect grants matching user
7729             if (userHandle == UserHandle.USER_ALL
7730                     || userHandle == UserHandle.getUserId(targetUid)) {
7731                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7732                     final UriPermission perm = it.next();
7733
7734                     // Only inspect grants matching package
7735                     if (packageName == null || perm.sourcePkg.equals(packageName)
7736                             || perm.targetPkg.equals(packageName)) {
7737                         persistChanged |= perm.revokeModes(persistable
7738                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7739
7740                         // Only remove when no modes remain; any persisted grants
7741                         // will keep this alive.
7742                         if (perm.modeFlags == 0) {
7743                             it.remove();
7744                         }
7745                     }
7746                 }
7747
7748                 if (perms.isEmpty()) {
7749                     mGrantedUriPermissions.remove(targetUid);
7750                     N--;
7751                     i--;
7752                 }
7753             }
7754         }
7755
7756         if (persistChanged) {
7757             schedulePersistUriGrants();
7758         }
7759     }
7760
7761     @Override
7762     public IBinder newUriPermissionOwner(String name) {
7763         enforceNotIsolatedCaller("newUriPermissionOwner");
7764         synchronized(this) {
7765             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7766             return owner.getExternalTokenLocked();
7767         }
7768     }
7769
7770     /**
7771      * @param uri This uri must NOT contain an embedded userId.
7772      * @param sourceUserId The userId in which the uri is to be resolved.
7773      * @param targetUserId The userId of the app that receives the grant.
7774      */
7775     @Override
7776     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7777             final int modeFlags, int sourceUserId, int targetUserId) {
7778         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7779                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7780         synchronized(this) {
7781             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7782             if (owner == null) {
7783                 throw new IllegalArgumentException("Unknown owner: " + token);
7784             }
7785             if (fromUid != Binder.getCallingUid()) {
7786                 if (Binder.getCallingUid() != Process.myUid()) {
7787                     // Only system code can grant URI permissions on behalf
7788                     // of other users.
7789                     throw new SecurityException("nice try");
7790                 }
7791             }
7792             if (targetPkg == null) {
7793                 throw new IllegalArgumentException("null target");
7794             }
7795             if (uri == null) {
7796                 throw new IllegalArgumentException("null uri");
7797             }
7798
7799             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7800                     modeFlags, owner, targetUserId);
7801         }
7802     }
7803
7804     /**
7805      * @param uri This uri must NOT contain an embedded userId.
7806      * @param userId The userId in which the uri is to be resolved.
7807      */
7808     @Override
7809     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7810         synchronized(this) {
7811             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7812             if (owner == null) {
7813                 throw new IllegalArgumentException("Unknown owner: " + token);
7814             }
7815
7816             if (uri == null) {
7817                 owner.removeUriPermissionsLocked(mode);
7818             } else {
7819                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7820             }
7821         }
7822     }
7823
7824     private void schedulePersistUriGrants() {
7825         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7826             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7827                     10 * DateUtils.SECOND_IN_MILLIS);
7828         }
7829     }
7830
7831     private void writeGrantedUriPermissions() {
7832         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7833
7834         // Snapshot permissions so we can persist without lock
7835         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7836         synchronized (this) {
7837             final int size = mGrantedUriPermissions.size();
7838             for (int i = 0; i < size; i++) {
7839                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7840                 for (UriPermission perm : perms.values()) {
7841                     if (perm.persistedModeFlags != 0) {
7842                         persist.add(perm.snapshot());
7843                     }
7844                 }
7845             }
7846         }
7847
7848         FileOutputStream fos = null;
7849         try {
7850             fos = mGrantFile.startWrite();
7851
7852             XmlSerializer out = new FastXmlSerializer();
7853             out.setOutput(fos, "utf-8");
7854             out.startDocument(null, true);
7855             out.startTag(null, TAG_URI_GRANTS);
7856             for (UriPermission.Snapshot perm : persist) {
7857                 out.startTag(null, TAG_URI_GRANT);
7858                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7859                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7860                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7861                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7862                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7863                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7864                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7865                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7866                 out.endTag(null, TAG_URI_GRANT);
7867             }
7868             out.endTag(null, TAG_URI_GRANTS);
7869             out.endDocument();
7870
7871             mGrantFile.finishWrite(fos);
7872         } catch (IOException e) {
7873             if (fos != null) {
7874                 mGrantFile.failWrite(fos);
7875             }
7876         }
7877     }
7878
7879     private void readGrantedUriPermissionsLocked() {
7880         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7881
7882         final long now = System.currentTimeMillis();
7883
7884         FileInputStream fis = null;
7885         try {
7886             fis = mGrantFile.openRead();
7887             final XmlPullParser in = Xml.newPullParser();
7888             in.setInput(fis, null);
7889
7890             int type;
7891             while ((type = in.next()) != END_DOCUMENT) {
7892                 final String tag = in.getName();
7893                 if (type == START_TAG) {
7894                     if (TAG_URI_GRANT.equals(tag)) {
7895                         final int sourceUserId;
7896                         final int targetUserId;
7897                         final int userHandle = readIntAttribute(in,
7898                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7899                         if (userHandle != UserHandle.USER_NULL) {
7900                             // For backwards compatibility.
7901                             sourceUserId = userHandle;
7902                             targetUserId = userHandle;
7903                         } else {
7904                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7905                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7906                         }
7907                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7908                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7909                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7910                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7911                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7912                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7913
7914                         // Sanity check that provider still belongs to source package
7915                         final ProviderInfo pi = getProviderInfoLocked(
7916                                 uri.getAuthority(), sourceUserId);
7917                         if (pi != null && sourcePkg.equals(pi.packageName)) {
7918                             int targetUid = -1;
7919                             try {
7920                                 targetUid = AppGlobals.getPackageManager()
7921                                         .getPackageUid(targetPkg, targetUserId);
7922                             } catch (RemoteException e) {
7923                             }
7924                             if (targetUid != -1) {
7925                                 final UriPermission perm = findOrCreateUriPermissionLocked(
7926                                         sourcePkg, targetPkg, targetUid,
7927                                         new GrantUri(sourceUserId, uri, prefix));
7928                                 perm.initPersistedModes(modeFlags, createdTime);
7929                             }
7930                         } else {
7931                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7932                                     + " but instead found " + pi);
7933                         }
7934                     }
7935                 }
7936             }
7937         } catch (FileNotFoundException e) {
7938             // Missing grants is okay
7939         } catch (IOException e) {
7940             Slog.wtf(TAG, "Failed reading Uri grants", e);
7941         } catch (XmlPullParserException e) {
7942             Slog.wtf(TAG, "Failed reading Uri grants", e);
7943         } finally {
7944             IoUtils.closeQuietly(fis);
7945         }
7946     }
7947
7948     /**
7949      * @param uri This uri must NOT contain an embedded userId.
7950      * @param userId The userId in which the uri is to be resolved.
7951      */
7952     @Override
7953     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7954         enforceNotIsolatedCaller("takePersistableUriPermission");
7955
7956         Preconditions.checkFlagsArgument(modeFlags,
7957                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7958
7959         synchronized (this) {
7960             final int callingUid = Binder.getCallingUid();
7961             boolean persistChanged = false;
7962             GrantUri grantUri = new GrantUri(userId, uri, 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
7969             final boolean exactValid = (exactPerm != null)
7970                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7971             final boolean prefixValid = (prefixPerm != null)
7972                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7973
7974             if (!(exactValid || prefixValid)) {
7975                 throw new SecurityException("No persistable permission grants found for UID "
7976                         + callingUid + " and Uri " + grantUri.toSafeString());
7977             }
7978
7979             if (exactValid) {
7980                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7981             }
7982             if (prefixValid) {
7983                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7984             }
7985
7986             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7987
7988             if (persistChanged) {
7989                 schedulePersistUriGrants();
7990             }
7991         }
7992     }
7993
7994     /**
7995      * @param uri This uri must NOT contain an embedded userId.
7996      * @param userId The userId in which the uri is to be resolved.
7997      */
7998     @Override
7999     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8000         enforceNotIsolatedCaller("releasePersistableUriPermission");
8001
8002         Preconditions.checkFlagsArgument(modeFlags,
8003                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8004
8005         synchronized (this) {
8006             final int callingUid = Binder.getCallingUid();
8007             boolean persistChanged = false;
8008
8009             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8010                     new GrantUri(userId, uri, false));
8011             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8012                     new GrantUri(userId, uri, true));
8013             if (exactPerm == null && prefixPerm == null) {
8014                 throw new SecurityException("No permission grants found for UID " + callingUid
8015                         + " and Uri " + uri.toSafeString());
8016             }
8017
8018             if (exactPerm != null) {
8019                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8020                 removeUriPermissionIfNeededLocked(exactPerm);
8021             }
8022             if (prefixPerm != null) {
8023                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8024                 removeUriPermissionIfNeededLocked(prefixPerm);
8025             }
8026
8027             if (persistChanged) {
8028                 schedulePersistUriGrants();
8029             }
8030         }
8031     }
8032
8033     /**
8034      * Prune any older {@link UriPermission} for the given UID until outstanding
8035      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8036      *
8037      * @return if any mutations occured that require persisting.
8038      */
8039     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8040         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8041         if (perms == null) return false;
8042         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8043
8044         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8045         for (UriPermission perm : perms.values()) {
8046             if (perm.persistedModeFlags != 0) {
8047                 persisted.add(perm);
8048             }
8049         }
8050
8051         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8052         if (trimCount <= 0) return false;
8053
8054         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8055         for (int i = 0; i < trimCount; i++) {
8056             final UriPermission perm = persisted.get(i);
8057
8058             if (DEBUG_URI_PERMISSION) {
8059                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8060             }
8061
8062             perm.releasePersistableModes(~0);
8063             removeUriPermissionIfNeededLocked(perm);
8064         }
8065
8066         return true;
8067     }
8068
8069     @Override
8070     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8071             String packageName, boolean incoming) {
8072         enforceNotIsolatedCaller("getPersistedUriPermissions");
8073         Preconditions.checkNotNull(packageName, "packageName");
8074
8075         final int callingUid = Binder.getCallingUid();
8076         final IPackageManager pm = AppGlobals.getPackageManager();
8077         try {
8078             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8079             if (packageUid != callingUid) {
8080                 throw new SecurityException(
8081                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8082             }
8083         } catch (RemoteException e) {
8084             throw new SecurityException("Failed to verify package name ownership");
8085         }
8086
8087         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8088         synchronized (this) {
8089             if (incoming) {
8090                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8091                         callingUid);
8092                 if (perms == null) {
8093                     Slog.w(TAG, "No permission grants found for " + packageName);
8094                 } else {
8095                     for (UriPermission perm : perms.values()) {
8096                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8097                             result.add(perm.buildPersistedPublicApiObject());
8098                         }
8099                     }
8100                 }
8101             } else {
8102                 final int size = mGrantedUriPermissions.size();
8103                 for (int i = 0; i < size; i++) {
8104                     final ArrayMap<GrantUri, UriPermission> perms =
8105                             mGrantedUriPermissions.valueAt(i);
8106                     for (UriPermission perm : perms.values()) {
8107                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8108                             result.add(perm.buildPersistedPublicApiObject());
8109                         }
8110                     }
8111                 }
8112             }
8113         }
8114         return new ParceledListSlice<android.content.UriPermission>(result);
8115     }
8116
8117     @Override
8118     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8119         synchronized (this) {
8120             ProcessRecord app =
8121                 who != null ? getRecordForAppLocked(who) : null;
8122             if (app == null) return;
8123
8124             Message msg = Message.obtain();
8125             msg.what = WAIT_FOR_DEBUGGER_MSG;
8126             msg.obj = app;
8127             msg.arg1 = waiting ? 1 : 0;
8128             mHandler.sendMessage(msg);
8129         }
8130     }
8131
8132     @Override
8133     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8134         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8135         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8136         outInfo.availMem = Process.getFreeMemory();
8137         outInfo.totalMem = Process.getTotalMemory();
8138         outInfo.threshold = homeAppMem;
8139         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8140         outInfo.hiddenAppThreshold = cachedAppMem;
8141         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8142                 ProcessList.SERVICE_ADJ);
8143         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8144                 ProcessList.VISIBLE_APP_ADJ);
8145         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8146                 ProcessList.FOREGROUND_APP_ADJ);
8147     }
8148     
8149     // =========================================================
8150     // TASK MANAGEMENT
8151     // =========================================================
8152
8153     @Override
8154     public List<IAppTask> getAppTasks(String callingPackage) {
8155         int callingUid = Binder.getCallingUid();
8156         long ident = Binder.clearCallingIdentity();
8157
8158         synchronized(this) {
8159             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8160             try {
8161                 if (localLOGV) Slog.v(TAG, "getAppTasks");
8162
8163                 final int N = mRecentTasks.size();
8164                 for (int i = 0; i < N; i++) {
8165                     TaskRecord tr = mRecentTasks.get(i);
8166                     // Skip tasks that do not match the caller.  We don't need to verify
8167                     // callingPackage, because we are also limiting to callingUid and know
8168                     // that will limit to the correct security sandbox.
8169                     if (tr.effectiveUid != callingUid) {
8170                         continue;
8171                     }
8172                     Intent intent = tr.getBaseIntent();
8173                     if (intent == null ||
8174                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8175                         continue;
8176                     }
8177                     ActivityManager.RecentTaskInfo taskInfo =
8178                             createRecentTaskInfoFromTaskRecord(tr);
8179                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8180                     list.add(taskImpl);
8181                 }
8182             } finally {
8183                 Binder.restoreCallingIdentity(ident);
8184             }
8185             return list;
8186         }
8187     }
8188
8189     @Override
8190     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8191         final int callingUid = Binder.getCallingUid();
8192         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8193
8194         synchronized(this) {
8195             if (localLOGV) Slog.v(
8196                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8197
8198             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8199                     callingUid);
8200
8201             // TODO: Improve with MRU list from all ActivityStacks.
8202             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8203         }
8204
8205         return list;
8206     }
8207
8208     TaskRecord getMostRecentTask() {
8209         return mRecentTasks.get(0);
8210     }
8211
8212     /**
8213      * Creates a new RecentTaskInfo from a TaskRecord.
8214      */
8215     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8216         // Update the task description to reflect any changes in the task stack
8217         tr.updateTaskDescription();
8218
8219         // Compose the recent task info
8220         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8221         rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8222         rti.persistentId = tr.taskId;
8223         rti.baseIntent = new Intent(tr.getBaseIntent());
8224         rti.origActivity = tr.origActivity;
8225         rti.description = tr.lastDescription;
8226         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8227         rti.userId = tr.userId;
8228         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8229         rti.firstActiveTime = tr.firstActiveTime;
8230         rti.lastActiveTime = tr.lastActiveTime;
8231         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8232         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8233         return rti;
8234     }
8235
8236     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8237         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8238                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8239         if (!allowed) {
8240             if (checkPermission(android.Manifest.permission.GET_TASKS,
8241                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8242                 // Temporary compatibility: some existing apps on the system image may
8243                 // still be requesting the old permission and not switched to the new
8244                 // one; if so, we'll still allow them full access.  This means we need
8245                 // to see if they are holding the old permission and are a system app.
8246                 try {
8247                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8248                         allowed = true;
8249                         Slog.w(TAG, caller + ": caller " + callingUid
8250                                 + " is using old GET_TASKS but privileged; allowing");
8251                     }
8252                 } catch (RemoteException e) {
8253                 }
8254             }
8255         }
8256         if (!allowed) {
8257             Slog.w(TAG, caller + ": caller " + callingUid
8258                     + " does not hold REAL_GET_TASKS; limiting output");
8259         }
8260         return allowed;
8261     }
8262
8263     @Override
8264     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8265         final int callingUid = Binder.getCallingUid();
8266         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8267                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8268
8269         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8270         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8271         synchronized (this) {
8272             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8273                     callingUid);
8274             final boolean detailed = checkCallingPermission(
8275                     android.Manifest.permission.GET_DETAILED_TASKS)
8276                     == PackageManager.PERMISSION_GRANTED;
8277
8278             final int N = mRecentTasks.size();
8279             ArrayList<ActivityManager.RecentTaskInfo> res
8280                     = new ArrayList<ActivityManager.RecentTaskInfo>(
8281                             maxNum < N ? maxNum : N);
8282
8283             final Set<Integer> includedUsers;
8284             if (includeProfiles) {
8285                 includedUsers = getProfileIdsLocked(userId);
8286             } else {
8287                 includedUsers = new HashSet<Integer>();
8288             }
8289             includedUsers.add(Integer.valueOf(userId));
8290
8291             for (int i=0; i<N && maxNum > 0; i++) {
8292                 TaskRecord tr = mRecentTasks.get(i);
8293                 // Only add calling user or related users recent tasks
8294                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8295                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8296                     continue;
8297                 }
8298
8299                 // Return the entry if desired by the caller.  We always return
8300                 // the first entry, because callers always expect this to be the
8301                 // foreground app.  We may filter others if the caller has
8302                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8303                 // we should exclude the entry.
8304
8305                 if (i == 0
8306                         || withExcluded
8307                         || (tr.intent == null)
8308                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8309                                 == 0)) {
8310                     if (!allowed) {
8311                         // If the caller doesn't have the GET_TASKS permission, then only
8312                         // allow them to see a small subset of tasks -- their own and home.
8313                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8314                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8315                             continue;
8316                         }
8317                     }
8318                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8319                         if (tr.stack != null && tr.stack.isHomeStack()) {
8320                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8321                             continue;
8322                         }
8323                     }
8324                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8325                         // Don't include auto remove tasks that are finished or finishing.
8326                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8327                                 + tr);
8328                         continue;
8329                     }
8330                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8331                             && !tr.isAvailable) {
8332                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8333                         continue;
8334                     }
8335
8336                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8337                     if (!detailed) {
8338                         rti.baseIntent.replaceExtras((Bundle)null);
8339                     }
8340
8341                     res.add(rti);
8342                     maxNum--;
8343                 }
8344             }
8345             return res;
8346         }
8347     }
8348
8349     private TaskRecord recentTaskForIdLocked(int id) {
8350         final int N = mRecentTasks.size();
8351             for (int i=0; i<N; i++) {
8352                 TaskRecord tr = mRecentTasks.get(i);
8353                 if (tr.taskId == id) {
8354                     return tr;
8355                 }
8356             }
8357             return null;
8358     }
8359
8360     @Override
8361     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8362         synchronized (this) {
8363             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8364                     "getTaskThumbnail()");
8365             TaskRecord tr = recentTaskForIdLocked(id);
8366             if (tr != null) {
8367                 return tr.getTaskThumbnailLocked();
8368             }
8369         }
8370         return null;
8371     }
8372
8373     @Override
8374     public int addAppTask(IBinder activityToken, Intent intent,
8375             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8376         final int callingUid = Binder.getCallingUid();
8377         final long callingIdent = Binder.clearCallingIdentity();
8378
8379         try {
8380             synchronized (this) {
8381                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8382                 if (r == null) {
8383                     throw new IllegalArgumentException("Activity does not exist; token="
8384                             + activityToken);
8385                 }
8386                 ComponentName comp = intent.getComponent();
8387                 if (comp == null) {
8388                     throw new IllegalArgumentException("Intent " + intent
8389                             + " must specify explicit component");
8390                 }
8391                 if (thumbnail.getWidth() != mThumbnailWidth
8392                         || thumbnail.getHeight() != mThumbnailHeight) {
8393                     throw new IllegalArgumentException("Bad thumbnail size: got "
8394                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8395                             + mThumbnailWidth + "x" + mThumbnailHeight);
8396                 }
8397                 if (intent.getSelector() != null) {
8398                     intent.setSelector(null);
8399                 }
8400                 if (intent.getSourceBounds() != null) {
8401                     intent.setSourceBounds(null);
8402                 }
8403                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8404                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8405                         // The caller has added this as an auto-remove task...  that makes no
8406                         // sense, so turn off auto-remove.
8407                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8408                     }
8409                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8410                     // Must be a new task.
8411                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8412                 }
8413                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8414                     mLastAddedTaskActivity = null;
8415                 }
8416                 ActivityInfo ainfo = mLastAddedTaskActivity;
8417                 if (ainfo == null) {
8418                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8419                             comp, 0, UserHandle.getUserId(callingUid));
8420                     if (ainfo.applicationInfo.uid != callingUid) {
8421                         throw new SecurityException(
8422                                 "Can't add task for another application: target uid="
8423                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8424                     }
8425                 }
8426
8427                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8428                         intent, description);
8429
8430                 int trimIdx = trimRecentsForTask(task, false);
8431                 if (trimIdx >= 0) {
8432                     // If this would have caused a trim, then we'll abort because that
8433                     // means it would be added at the end of the list but then just removed.
8434                     return -1;
8435                 }
8436
8437                 final int N = mRecentTasks.size();
8438                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8439                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8440                     tr.removedFromRecents(mTaskPersister);
8441                 }
8442
8443                 task.inRecents = true;
8444                 mRecentTasks.add(task);
8445                 r.task.stack.addTask(task, false, false);
8446
8447                 task.setLastThumbnail(thumbnail);
8448                 task.freeLastThumbnail();
8449
8450                 return task.taskId;
8451             }
8452         } finally {
8453             Binder.restoreCallingIdentity(callingIdent);
8454         }
8455     }
8456
8457     @Override
8458     public Point getAppTaskThumbnailSize() {
8459         synchronized (this) {
8460             return new Point(mThumbnailWidth,  mThumbnailHeight);
8461         }
8462     }
8463
8464     @Override
8465     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8466         synchronized (this) {
8467             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8468             if (r != null) {
8469                 r.setTaskDescription(td);
8470                 r.task.updateTaskDescription();
8471             }
8472         }
8473     }
8474
8475     @Override
8476     public Bitmap getTaskDescriptionIcon(String filename) {
8477         if (!FileUtils.isValidExtFilename(filename)
8478                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8479             throw new IllegalArgumentException("Bad filename: " + filename);
8480         }
8481         return mTaskPersister.getTaskDescriptionIcon(filename);
8482     }
8483
8484     private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8485         mRecentTasks.remove(tr);
8486         tr.removedFromRecents(mTaskPersister);
8487         final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8488         Intent baseIntent = new Intent(
8489                 tr.intent != null ? tr.intent : tr.affinityIntent);
8490         ComponentName component = baseIntent.getComponent();
8491         if (component == null) {
8492             Slog.w(TAG, "Now component for base intent of task: " + tr);
8493             return;
8494         }
8495
8496         // Find any running services associated with this app.
8497         mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8498
8499         if (killProcesses) {
8500             // Find any running processes associated with this app.
8501             final String pkg = component.getPackageName();
8502             ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8503             ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8504             for (int i=0; i<pmap.size(); i++) {
8505                 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8506                 for (int j=0; j<uids.size(); j++) {
8507                     ProcessRecord proc = uids.valueAt(j);
8508                     if (proc.userId != tr.userId) {
8509                         continue;
8510                     }
8511                     if (!proc.pkgList.containsKey(pkg)) {
8512                         continue;
8513                     }
8514                     procs.add(proc);
8515                 }
8516             }
8517
8518             // Kill the running processes.
8519             for (int i=0; i<procs.size(); i++) {
8520                 ProcessRecord pr = procs.get(i);
8521                 if (pr == mHomeProcess) {
8522                     // Don't kill the home process along with tasks from the same package.
8523                     continue;
8524                 }
8525                 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8526                     pr.kill("remove task", true);
8527                 } else {
8528                     pr.waitingToKill = "remove task";
8529                 }
8530             }
8531         }
8532     }
8533
8534     /**
8535      * Removes the task with the specified task id.
8536      *
8537      * @param taskId Identifier of the task to be removed.
8538      * @param flags Additional operational flags.  May be 0 or
8539      * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8540      * @return Returns true if the given task was found and removed.
8541      */
8542     private boolean removeTaskByIdLocked(int taskId, int flags) {
8543         TaskRecord tr = recentTaskForIdLocked(taskId);
8544         if (tr != null) {
8545             tr.removeTaskActivitiesLocked();
8546             cleanUpRemovedTaskLocked(tr, flags);
8547             if (tr.isPersistable) {
8548                 notifyTaskPersisterLocked(null, true);
8549             }
8550             return true;
8551         }
8552         return false;
8553     }
8554
8555     @Override
8556     public boolean removeTask(int taskId, int flags) {
8557         synchronized (this) {
8558             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8559                     "removeTask()");
8560             long ident = Binder.clearCallingIdentity();
8561             try {
8562                 return removeTaskByIdLocked(taskId, flags);
8563             } finally {
8564                 Binder.restoreCallingIdentity(ident);
8565             }
8566         }
8567     }
8568     
8569     /**
8570      * TODO: Add mController hook
8571      */
8572     @Override
8573     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8574         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8575                 "moveTaskToFront()");
8576
8577         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8578         synchronized(this) {
8579             moveTaskToFrontLocked(taskId, flags, options);
8580         }
8581     }
8582
8583     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8584         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8585                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8586             ActivityOptions.abort(options);
8587             return;
8588         }
8589         final long origId = Binder.clearCallingIdentity();
8590         try {
8591             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8592             if (task == null) {
8593                 return;
8594             }
8595             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8596                 mStackSupervisor.showLockTaskToast();
8597                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8598                 return;
8599             }
8600             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8601             if (prev != null && prev.isRecentsActivity()) {
8602                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8603             }
8604             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8605         } finally {
8606             Binder.restoreCallingIdentity(origId);
8607         }
8608         ActivityOptions.abort(options);
8609     }
8610
8611     @Override
8612     public void moveTaskToBack(int taskId) {
8613         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8614                 "moveTaskToBack()");
8615
8616         synchronized(this) {
8617             TaskRecord tr = recentTaskForIdLocked(taskId);
8618             if (tr != null) {
8619                 if (tr == mStackSupervisor.mLockTaskModeTask) {
8620                     mStackSupervisor.showLockTaskToast();
8621                     return;
8622                 }
8623                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8624                 ActivityStack stack = tr.stack;
8625                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8626                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8627                             Binder.getCallingUid(), -1, -1, "Task to back")) {
8628                         return;
8629                     }
8630                 }
8631                 final long origId = Binder.clearCallingIdentity();
8632                 try {
8633                     stack.moveTaskToBackLocked(taskId, null);
8634                 } finally {
8635                     Binder.restoreCallingIdentity(origId);
8636                 }
8637             }
8638         }
8639     }
8640
8641     /**
8642      * Moves an activity, and all of the other activities within the same task, to the bottom
8643      * of the history stack.  The activity's order within the task is unchanged.
8644      * 
8645      * @param token A reference to the activity we wish to move
8646      * @param nonRoot If false then this only works if the activity is the root
8647      *                of a task; if true it will work for any activity in a task.
8648      * @return Returns true if the move completed, false if not.
8649      */
8650     @Override
8651     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8652         enforceNotIsolatedCaller("moveActivityTaskToBack");
8653         synchronized(this) {
8654             final long origId = Binder.clearCallingIdentity();
8655             try {
8656                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8657                 if (taskId >= 0) {
8658                     if ((mStackSupervisor.mLockTaskModeTask != null)
8659                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8660                         mStackSupervisor.showLockTaskToast();
8661                         return false;
8662                     }
8663                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8664                 }
8665             } finally {
8666                 Binder.restoreCallingIdentity(origId);
8667             }
8668         }
8669         return false;
8670     }
8671
8672     @Override
8673     public void moveTaskBackwards(int task) {
8674         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8675                 "moveTaskBackwards()");
8676
8677         synchronized(this) {
8678             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8679                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8680                 return;
8681             }
8682             final long origId = Binder.clearCallingIdentity();
8683             moveTaskBackwardsLocked(task);
8684             Binder.restoreCallingIdentity(origId);
8685         }
8686     }
8687
8688     private final void moveTaskBackwardsLocked(int task) {
8689         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8690     }
8691
8692     @Override
8693     public IBinder getHomeActivityToken() throws RemoteException {
8694         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8695                 "getHomeActivityToken()");
8696         synchronized (this) {
8697             return mStackSupervisor.getHomeActivityToken();
8698         }
8699     }
8700
8701     @Override
8702     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8703             IActivityContainerCallback callback) throws RemoteException {
8704         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8705                 "createActivityContainer()");
8706         synchronized (this) {
8707             if (parentActivityToken == null) {
8708                 throw new IllegalArgumentException("parent token must not be null");
8709             }
8710             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8711             if (r == null) {
8712                 return null;
8713             }
8714             if (callback == null) {
8715                 throw new IllegalArgumentException("callback must not be null");
8716             }
8717             return mStackSupervisor.createActivityContainer(r, callback);
8718         }
8719     }
8720
8721     @Override
8722     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8723         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8724                 "deleteActivityContainer()");
8725         synchronized (this) {
8726             mStackSupervisor.deleteActivityContainer(container);
8727         }
8728     }
8729
8730     @Override
8731     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8732         synchronized (this) {
8733             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8734             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8735                 return stack.mActivityContainer.getDisplayId();
8736             }
8737             return Display.DEFAULT_DISPLAY;
8738         }
8739     }
8740
8741     @Override
8742     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8743         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744                 "moveTaskToStack()");
8745         if (stackId == HOME_STACK_ID) {
8746             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8747                     new RuntimeException("here").fillInStackTrace());
8748         }
8749         synchronized (this) {
8750             long ident = Binder.clearCallingIdentity();
8751             try {
8752                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8753                         + stackId + " toTop=" + toTop);
8754                 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8755             } finally {
8756                 Binder.restoreCallingIdentity(ident);
8757             }
8758         }
8759     }
8760
8761     @Override
8762     public void resizeStack(int stackBoxId, Rect bounds) {
8763         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8764                 "resizeStackBox()");
8765         long ident = Binder.clearCallingIdentity();
8766         try {
8767             mWindowManager.resizeStack(stackBoxId, bounds);
8768         } finally {
8769             Binder.restoreCallingIdentity(ident);
8770         }
8771     }
8772
8773     @Override
8774     public List<StackInfo> getAllStackInfos() {
8775         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8776                 "getAllStackInfos()");
8777         long ident = Binder.clearCallingIdentity();
8778         try {
8779             synchronized (this) {
8780                 return mStackSupervisor.getAllStackInfosLocked();
8781             }
8782         } finally {
8783             Binder.restoreCallingIdentity(ident);
8784         }
8785     }
8786
8787     @Override
8788     public StackInfo getStackInfo(int stackId) {
8789         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8790                 "getStackInfo()");
8791         long ident = Binder.clearCallingIdentity();
8792         try {
8793             synchronized (this) {
8794                 return mStackSupervisor.getStackInfoLocked(stackId);
8795             }
8796         } finally {
8797             Binder.restoreCallingIdentity(ident);
8798         }
8799     }
8800
8801     @Override
8802     public boolean isInHomeStack(int taskId) {
8803         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8804                 "getStackInfo()");
8805         long ident = Binder.clearCallingIdentity();
8806         try {
8807             synchronized (this) {
8808                 TaskRecord tr = recentTaskForIdLocked(taskId);
8809                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8810             }
8811         } finally {
8812             Binder.restoreCallingIdentity(ident);
8813         }
8814     }
8815
8816     @Override
8817     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8818         synchronized(this) {
8819             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8820         }
8821     }
8822
8823     private boolean isLockTaskAuthorized(String pkg) {
8824         final DevicePolicyManager dpm = (DevicePolicyManager)
8825                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8826         try {
8827             int uid = mContext.getPackageManager().getPackageUid(pkg,
8828                     Binder.getCallingUserHandle().getIdentifier());
8829             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8830         } catch (NameNotFoundException e) {
8831             return false;
8832         }
8833     }
8834
8835     void startLockTaskMode(TaskRecord task) {
8836         final String pkg;
8837         synchronized (this) {
8838             pkg = task.intent.getComponent().getPackageName();
8839         }
8840         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8841         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8842             final TaskRecord taskRecord = task;
8843             mHandler.post(new Runnable() {
8844                 @Override
8845                 public void run() {
8846                     mLockToAppRequest.showLockTaskPrompt(taskRecord);
8847                 }
8848             });
8849             return;
8850         }
8851         long ident = Binder.clearCallingIdentity();
8852         try {
8853             synchronized (this) {
8854                 // Since we lost lock on task, make sure it is still there.
8855                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8856                 if (task != null) {
8857                     if (!isSystemInitiated
8858                             && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8859                         throw new IllegalArgumentException("Invalid task, not in foreground");
8860                     }
8861                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8862                 }
8863             }
8864         } finally {
8865             Binder.restoreCallingIdentity(ident);
8866         }
8867     }
8868
8869     @Override
8870     public void startLockTaskMode(int taskId) {
8871         final TaskRecord task;
8872         long ident = Binder.clearCallingIdentity();
8873         try {
8874             synchronized (this) {
8875                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8876             }
8877         } finally {
8878             Binder.restoreCallingIdentity(ident);
8879         }
8880         if (task != null) {
8881             startLockTaskMode(task);
8882         }
8883     }
8884
8885     @Override
8886     public void startLockTaskMode(IBinder token) {
8887         final TaskRecord task;
8888         long ident = Binder.clearCallingIdentity();
8889         try {
8890             synchronized (this) {
8891                 final ActivityRecord r = ActivityRecord.forToken(token);
8892                 if (r == null) {
8893                     return;
8894                 }
8895                 task = r.task;
8896             }
8897         } finally {
8898             Binder.restoreCallingIdentity(ident);
8899         }
8900         if (task != null) {
8901             startLockTaskMode(task);
8902         }
8903     }
8904
8905     @Override
8906     public void startLockTaskModeOnCurrent() throws RemoteException {
8907         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8908                 "startLockTaskModeOnCurrent");
8909         ActivityRecord r = null;
8910         synchronized (this) {
8911             r = mStackSupervisor.topRunningActivityLocked();
8912         }
8913         startLockTaskMode(r.task);
8914     }
8915
8916     @Override
8917     public void stopLockTaskMode() {
8918         // Verify that the user matches the package of the intent for the TaskRecord
8919         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8920         // and stopLockTaskMode.
8921         final int callingUid = Binder.getCallingUid();
8922         if (callingUid != Process.SYSTEM_UID) {
8923             try {
8924                 String pkg =
8925                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8926                 int uid = mContext.getPackageManager().getPackageUid(pkg,
8927                         Binder.getCallingUserHandle().getIdentifier());
8928                 if (uid != callingUid) {
8929                     throw new SecurityException("Invalid uid, expected " + uid);
8930                 }
8931             } catch (NameNotFoundException e) {
8932                 Log.d(TAG, "stopLockTaskMode " + e);
8933                 return;
8934             }
8935         }
8936         long ident = Binder.clearCallingIdentity();
8937         try {
8938             Log.d(TAG, "stopLockTaskMode");
8939             // Stop lock task
8940             synchronized (this) {
8941                 mStackSupervisor.setLockTaskModeLocked(null, false);
8942             }
8943         } finally {
8944             Binder.restoreCallingIdentity(ident);
8945         }
8946     }
8947
8948     @Override
8949     public void stopLockTaskModeOnCurrent() throws RemoteException {
8950         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8951                 "stopLockTaskModeOnCurrent");
8952         long ident = Binder.clearCallingIdentity();
8953         try {
8954             stopLockTaskMode();
8955         } finally {
8956             Binder.restoreCallingIdentity(ident);
8957         }
8958     }
8959
8960     @Override
8961     public boolean isInLockTaskMode() {
8962         synchronized (this) {
8963             return mStackSupervisor.isInLockTaskMode();
8964         }
8965     }
8966
8967     // =========================================================
8968     // CONTENT PROVIDERS
8969     // =========================================================
8970
8971     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8972         List<ProviderInfo> providers = null;
8973         try {
8974             providers = AppGlobals.getPackageManager().
8975                 queryContentProviders(app.processName, app.uid,
8976                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8977         } catch (RemoteException ex) {
8978         }
8979         if (DEBUG_MU)
8980             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8981         int userId = app.userId;
8982         if (providers != null) {
8983             int N = providers.size();
8984             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8985             for (int i=0; i<N; i++) {
8986                 ProviderInfo cpi =
8987                     (ProviderInfo)providers.get(i);
8988                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8989                         cpi.name, cpi.flags);
8990                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
8991                     // This is a singleton provider, but a user besides the
8992                     // default user is asking to initialize a process it runs
8993                     // in...  well, no, it doesn't actually run in this process,
8994                     // it runs in the process of the default user.  Get rid of it.
8995                     providers.remove(i);
8996                     N--;
8997                     i--;
8998                     continue;
8999                 }
9000
9001                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9002                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9003                 if (cpr == null) {
9004                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9005                     mProviderMap.putProviderByClass(comp, cpr);
9006                 }
9007                 if (DEBUG_MU)
9008                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9009                 app.pubProviders.put(cpi.name, cpr);
9010                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9011                     // Don't add this if it is a platform component that is marked
9012                     // to run in multiple processes, because this is actually
9013                     // part of the framework so doesn't make sense to track as a
9014                     // separate apk in the process.
9015                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9016                             mProcessStats);
9017                 }
9018                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9019             }
9020         }
9021         return providers;
9022     }
9023
9024     /**
9025      * Check if {@link ProcessRecord} has a possible chance at accessing the
9026      * given {@link ProviderInfo}. Final permission checking is always done
9027      * in {@link ContentProvider}.
9028      */
9029     private final String checkContentProviderPermissionLocked(
9030             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9031         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9032         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9033         boolean checkedGrants = false;
9034         if (checkUser) {
9035             // Looking for cross-user grants before enforcing the typical cross-users permissions
9036             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9037             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9038                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9039                     return null;
9040                 }
9041                 checkedGrants = true;
9042             }
9043             userId = handleIncomingUser(callingPid, callingUid, userId,
9044                     false, ALLOW_NON_FULL,
9045                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9046             if (userId != tmpTargetUserId) {
9047                 // When we actually went to determine the final targer user ID, this ended
9048                 // up different than our initial check for the authority.  This is because
9049                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9050                 // SELF.  So we need to re-check the grants again.
9051                 checkedGrants = false;
9052             }
9053         }
9054         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9055                 cpi.applicationInfo.uid, cpi.exported)
9056                 == PackageManager.PERMISSION_GRANTED) {
9057             return null;
9058         }
9059         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9060                 cpi.applicationInfo.uid, cpi.exported)
9061                 == PackageManager.PERMISSION_GRANTED) {
9062             return null;
9063         }
9064         
9065         PathPermission[] pps = cpi.pathPermissions;
9066         if (pps != null) {
9067             int i = pps.length;
9068             while (i > 0) {
9069                 i--;
9070                 PathPermission pp = pps[i];
9071                 String pprperm = pp.getReadPermission();
9072                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9073                         cpi.applicationInfo.uid, cpi.exported)
9074                         == PackageManager.PERMISSION_GRANTED) {
9075                     return null;
9076                 }
9077                 String ppwperm = pp.getWritePermission();
9078                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9079                         cpi.applicationInfo.uid, cpi.exported)
9080                         == PackageManager.PERMISSION_GRANTED) {
9081                     return null;
9082                 }
9083             }
9084         }
9085         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9086             return null;
9087         }
9088
9089         String msg;
9090         if (!cpi.exported) {
9091             msg = "Permission Denial: opening provider " + cpi.name
9092                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9093                     + ", uid=" + callingUid + ") that is not exported from uid "
9094                     + cpi.applicationInfo.uid;
9095         } else {
9096             msg = "Permission Denial: opening provider " + cpi.name
9097                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9098                     + ", uid=" + callingUid + ") requires "
9099                     + cpi.readPermission + " or " + cpi.writePermission;
9100         }
9101         Slog.w(TAG, msg);
9102         return msg;
9103     }
9104
9105     /**
9106      * Returns if the ContentProvider has granted a uri to callingUid
9107      */
9108     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9109         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9110         if (perms != null) {
9111             for (int i=perms.size()-1; i>=0; i--) {
9112                 GrantUri grantUri = perms.keyAt(i);
9113                 if (grantUri.sourceUserId == userId || !checkUser) {
9114                     if (matchesProvider(grantUri.uri, cpi)) {
9115                         return true;
9116                     }
9117                 }
9118             }
9119         }
9120         return false;
9121     }
9122
9123     /**
9124      * Returns true if the uri authority is one of the authorities specified in the provider.
9125      */
9126     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9127         String uriAuth = uri.getAuthority();
9128         String cpiAuth = cpi.authority;
9129         if (cpiAuth.indexOf(';') == -1) {
9130             return cpiAuth.equals(uriAuth);
9131         }
9132         String[] cpiAuths = cpiAuth.split(";");
9133         int length = cpiAuths.length;
9134         for (int i = 0; i < length; i++) {
9135             if (cpiAuths[i].equals(uriAuth)) return true;
9136         }
9137         return false;
9138     }
9139
9140     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9141             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9142         if (r != null) {
9143             for (int i=0; i<r.conProviders.size(); i++) {
9144                 ContentProviderConnection conn = r.conProviders.get(i);
9145                 if (conn.provider == cpr) {
9146                     if (DEBUG_PROVIDER) Slog.v(TAG,
9147                             "Adding provider requested by "
9148                             + r.processName + " from process "
9149                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9150                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9151                     if (stable) {
9152                         conn.stableCount++;
9153                         conn.numStableIncs++;
9154                     } else {
9155                         conn.unstableCount++;
9156                         conn.numUnstableIncs++;
9157                     }
9158                     return conn;
9159                 }
9160             }
9161             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9162             if (stable) {
9163                 conn.stableCount = 1;
9164                 conn.numStableIncs = 1;
9165             } else {
9166                 conn.unstableCount = 1;
9167                 conn.numUnstableIncs = 1;
9168             }
9169             cpr.connections.add(conn);
9170             r.conProviders.add(conn);
9171             return conn;
9172         }
9173         cpr.addExternalProcessHandleLocked(externalProcessToken);
9174         return null;
9175     }
9176
9177     boolean decProviderCountLocked(ContentProviderConnection conn,
9178             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9179         if (conn != null) {
9180             cpr = conn.provider;
9181             if (DEBUG_PROVIDER) Slog.v(TAG,
9182                     "Removing provider requested by "
9183                     + conn.client.processName + " from process "
9184                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9185                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9186             if (stable) {
9187                 conn.stableCount--;
9188             } else {
9189                 conn.unstableCount--;
9190             }
9191             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9192                 cpr.connections.remove(conn);
9193                 conn.client.conProviders.remove(conn);
9194                 return true;
9195             }
9196             return false;
9197         }
9198         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9199         return false;
9200     }
9201
9202     private void checkTime(long startTime, String where) {
9203         long now = SystemClock.elapsedRealtime();
9204         if ((now-startTime) > 1000) {
9205             // If we are taking more than a second, log about it.
9206             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9207         }
9208     }
9209
9210     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9211             String name, IBinder token, boolean stable, int userId) {
9212         ContentProviderRecord cpr;
9213         ContentProviderConnection conn = null;
9214         ProviderInfo cpi = null;
9215
9216         synchronized(this) {
9217             long startTime = SystemClock.elapsedRealtime();
9218
9219             ProcessRecord r = null;
9220             if (caller != null) {
9221                 r = getRecordForAppLocked(caller);
9222                 if (r == null) {
9223                     throw new SecurityException(
9224                             "Unable to find app for caller " + caller
9225                           + " (pid=" + Binder.getCallingPid()
9226                           + ") when getting content provider " + name);
9227                 }
9228             }
9229
9230             boolean checkCrossUser = true;
9231
9232             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9233
9234             // First check if this content provider has been published...
9235             cpr = mProviderMap.getProviderByName(name, userId);
9236             // If that didn't work, check if it exists for user 0 and then
9237             // verify that it's a singleton provider before using it.
9238             if (cpr == null && userId != UserHandle.USER_OWNER) {
9239                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9240                 if (cpr != null) {
9241                     cpi = cpr.info;
9242                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9243                             cpi.name, cpi.flags)
9244                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9245                         userId = UserHandle.USER_OWNER;
9246                         checkCrossUser = false;
9247                     } else {
9248                         cpr = null;
9249                         cpi = null;
9250                     }
9251                 }
9252             }
9253
9254             boolean providerRunning = cpr != null;
9255             if (providerRunning) {
9256                 cpi = cpr.info;
9257                 String msg;
9258                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9259                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9260                         != null) {
9261                     throw new SecurityException(msg);
9262                 }
9263                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9264
9265                 if (r != null && cpr.canRunHere(r)) {
9266                     // This provider has been published or is in the process
9267                     // of being published...  but it is also allowed to run
9268                     // in the caller's process, so don't make a connection
9269                     // and just let the caller instantiate its own instance.
9270                     ContentProviderHolder holder = cpr.newHolder(null);
9271                     // don't give caller the provider object, it needs
9272                     // to make its own.
9273                     holder.provider = null;
9274                     return holder;
9275                 }
9276
9277                 final long origId = Binder.clearCallingIdentity();
9278
9279                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9280
9281                 // In this case the provider instance already exists, so we can
9282                 // return it right away.
9283                 conn = incProviderCountLocked(r, cpr, token, stable);
9284                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9285                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9286                         // If this is a perceptible app accessing the provider,
9287                         // make sure to count it as being accessed and thus
9288                         // back up on the LRU list.  This is good because
9289                         // content providers are often expensive to start.
9290                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9291                         updateLruProcessLocked(cpr.proc, false, null);
9292                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9293                     }
9294                 }
9295
9296                 if (cpr.proc != null) {
9297                     if (false) {
9298                         if (cpr.name.flattenToShortString().equals(
9299                                 "com.android.providers.calendar/.CalendarProvider2")) {
9300                             Slog.v(TAG, "****************** KILLING "
9301                                 + cpr.name.flattenToShortString());
9302                             Process.killProcess(cpr.proc.pid);
9303                         }
9304                     }
9305                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9306                     boolean success = updateOomAdjLocked(cpr.proc);
9307                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9308                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9309                     // NOTE: there is still a race here where a signal could be
9310                     // pending on the process even though we managed to update its
9311                     // adj level.  Not sure what to do about this, but at least
9312                     // the race is now smaller.
9313                     if (!success) {
9314                         // Uh oh...  it looks like the provider's process
9315                         // has been killed on us.  We need to wait for a new
9316                         // process to be started, and make sure its death
9317                         // doesn't kill our process.
9318                         Slog.i(TAG,
9319                                 "Existing provider " + cpr.name.flattenToShortString()
9320                                 + " is crashing; detaching " + r);
9321                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9322                         checkTime(startTime, "getContentProviderImpl: before appDied");
9323                         appDiedLocked(cpr.proc);
9324                         checkTime(startTime, "getContentProviderImpl: after appDied");
9325                         if (!lastRef) {
9326                             // This wasn't the last ref our process had on
9327                             // the provider...  we have now been killed, bail.
9328                             return null;
9329                         }
9330                         providerRunning = false;
9331                         conn = null;
9332                     }
9333                 }
9334
9335                 Binder.restoreCallingIdentity(origId);
9336             }
9337
9338             boolean singleton;
9339             if (!providerRunning) {
9340                 try {
9341                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9342                     cpi = AppGlobals.getPackageManager().
9343                         resolveContentProvider(name,
9344                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9345                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9346                 } catch (RemoteException ex) {
9347                 }
9348                 if (cpi == null) {
9349                     return null;
9350                 }
9351                 // If the provider is a singleton AND
9352                 // (it's a call within the same user || the provider is a
9353                 // privileged app)
9354                 // Then allow connecting to the singleton provider
9355                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9356                         cpi.name, cpi.flags)
9357                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9358                 if (singleton) {
9359                     userId = UserHandle.USER_OWNER;
9360                 }
9361                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9362                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9363
9364                 String msg;
9365                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9366                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9367                         != null) {
9368                     throw new SecurityException(msg);
9369                 }
9370                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9371
9372                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9373                         && !cpi.processName.equals("system")) {
9374                     // If this content provider does not run in the system
9375                     // process, and the system is not yet ready to run other
9376                     // processes, then fail fast instead of hanging.
9377                     throw new IllegalArgumentException(
9378                             "Attempt to launch content provider before system ready");
9379                 }
9380
9381                 // Make sure that the user who owns this provider is started.  If not,
9382                 // we don't want to allow it to run.
9383                 if (mStartedUsers.get(userId) == null) {
9384                     Slog.w(TAG, "Unable to launch app "
9385                             + cpi.applicationInfo.packageName + "/"
9386                             + cpi.applicationInfo.uid + " for provider "
9387                             + name + ": user " + userId + " is stopped");
9388                     return null;
9389                 }
9390
9391                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9392                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9393                 cpr = mProviderMap.getProviderByClass(comp, userId);
9394                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9395                 final boolean firstClass = cpr == null;
9396                 if (firstClass) {
9397                     final long ident = Binder.clearCallingIdentity();
9398                     try {
9399                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9400                         ApplicationInfo ai =
9401                             AppGlobals.getPackageManager().
9402                                 getApplicationInfo(
9403                                         cpi.applicationInfo.packageName,
9404                                         STOCK_PM_FLAGS, userId);
9405                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9406                         if (ai == null) {
9407                             Slog.w(TAG, "No package info for content provider "
9408                                     + cpi.name);
9409                             return null;
9410                         }
9411                         ai = getAppInfoForUser(ai, userId);
9412                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9413                     } catch (RemoteException ex) {
9414                         // pm is in same process, this will never happen.
9415                     } finally {
9416                         Binder.restoreCallingIdentity(ident);
9417                     }
9418                 }
9419
9420                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9421
9422                 if (r != null && cpr.canRunHere(r)) {
9423                     // If this is a multiprocess provider, then just return its
9424                     // info and allow the caller to instantiate it.  Only do
9425                     // this if the provider is the same user as the caller's
9426                     // process, or can run as root (so can be in any process).
9427                     return cpr.newHolder(null);
9428                 }
9429
9430                 if (DEBUG_PROVIDER) {
9431                     RuntimeException e = new RuntimeException("here");
9432                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9433                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9434                 }
9435
9436                 // This is single process, and our app is now connecting to it.
9437                 // See if we are already in the process of launching this
9438                 // provider.
9439                 final int N = mLaunchingProviders.size();
9440                 int i;
9441                 for (i=0; i<N; i++) {
9442                     if (mLaunchingProviders.get(i) == cpr) {
9443                         break;
9444                     }
9445                 }
9446
9447                 // If the provider is not already being launched, then get it
9448                 // started.
9449                 if (i >= N) {
9450                     final long origId = Binder.clearCallingIdentity();
9451
9452                     try {
9453                         // Content provider is now in use, its package can't be stopped.
9454                         try {
9455                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9456                             AppGlobals.getPackageManager().setPackageStoppedState(
9457                                     cpr.appInfo.packageName, false, userId);
9458                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9459                         } catch (RemoteException e) {
9460                         } catch (IllegalArgumentException e) {
9461                             Slog.w(TAG, "Failed trying to unstop package "
9462                                     + cpr.appInfo.packageName + ": " + e);
9463                         }
9464
9465                         // Use existing process if already started
9466                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9467                         ProcessRecord proc = getProcessRecordLocked(
9468                                 cpi.processName, cpr.appInfo.uid, false);
9469                         if (proc != null && proc.thread != null) {
9470                             if (DEBUG_PROVIDER) {
9471                                 Slog.d(TAG, "Installing in existing process " + proc);
9472                             }
9473                             checkTime(startTime, "getContentProviderImpl: scheduling install");
9474                             proc.pubProviders.put(cpi.name, cpr);
9475                             try {
9476                                 proc.thread.scheduleInstallProvider(cpi);
9477                             } catch (RemoteException e) {
9478                             }
9479                         } else {
9480                             checkTime(startTime, "getContentProviderImpl: before start process");
9481                             proc = startProcessLocked(cpi.processName,
9482                                     cpr.appInfo, false, 0, "content provider",
9483                                     new ComponentName(cpi.applicationInfo.packageName,
9484                                             cpi.name), false, false, false);
9485                             checkTime(startTime, "getContentProviderImpl: after start process");
9486                             if (proc == null) {
9487                                 Slog.w(TAG, "Unable to launch app "
9488                                         + cpi.applicationInfo.packageName + "/"
9489                                         + cpi.applicationInfo.uid + " for provider "
9490                                         + name + ": process is bad");
9491                                 return null;
9492                             }
9493                         }
9494                         cpr.launchingApp = proc;
9495                         mLaunchingProviders.add(cpr);
9496                     } finally {
9497                         Binder.restoreCallingIdentity(origId);
9498                     }
9499                 }
9500
9501                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9502
9503                 // Make sure the provider is published (the same provider class
9504                 // may be published under multiple names).
9505                 if (firstClass) {
9506                     mProviderMap.putProviderByClass(comp, cpr);
9507                 }
9508
9509                 mProviderMap.putProviderByName(name, cpr);
9510                 conn = incProviderCountLocked(r, cpr, token, stable);
9511                 if (conn != null) {
9512                     conn.waiting = true;
9513                 }
9514             }
9515             checkTime(startTime, "getContentProviderImpl: done!");
9516         }
9517
9518         // Wait for the provider to be published...
9519         synchronized (cpr) {
9520             while (cpr.provider == null) {
9521                 if (cpr.launchingApp == null) {
9522                     Slog.w(TAG, "Unable to launch app "
9523                             + cpi.applicationInfo.packageName + "/"
9524                             + cpi.applicationInfo.uid + " for provider "
9525                             + name + ": launching app became null");
9526                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9527                             UserHandle.getUserId(cpi.applicationInfo.uid),
9528                             cpi.applicationInfo.packageName,
9529                             cpi.applicationInfo.uid, name);
9530                     return null;
9531                 }
9532                 try {
9533                     if (DEBUG_MU) {
9534                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9535                                 + cpr.launchingApp);
9536                     }
9537                     if (conn != null) {
9538                         conn.waiting = true;
9539                     }
9540                     cpr.wait();
9541                 } catch (InterruptedException ex) {
9542                 } finally {
9543                     if (conn != null) {
9544                         conn.waiting = false;
9545                     }
9546                 }
9547             }
9548         }
9549         return cpr != null ? cpr.newHolder(conn) : null;
9550     }
9551
9552     @Override
9553     public final ContentProviderHolder getContentProvider(
9554             IApplicationThread caller, String name, int userId, boolean stable) {
9555         enforceNotIsolatedCaller("getContentProvider");
9556         if (caller == null) {
9557             String msg = "null IApplicationThread when getting content provider "
9558                     + name;
9559             Slog.w(TAG, msg);
9560             throw new SecurityException(msg);
9561         }
9562         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9563         // with cross-user grant.
9564         return getContentProviderImpl(caller, name, null, stable, userId);
9565     }
9566
9567     public ContentProviderHolder getContentProviderExternal(
9568             String name, int userId, IBinder token) {
9569         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9570             "Do not have permission in call getContentProviderExternal()");
9571         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9572                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9573         return getContentProviderExternalUnchecked(name, token, userId);
9574     }
9575
9576     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9577             IBinder token, int userId) {
9578         return getContentProviderImpl(null, name, token, true, userId);
9579     }
9580
9581     /**
9582      * Drop a content provider from a ProcessRecord's bookkeeping
9583      */
9584     public void removeContentProvider(IBinder connection, boolean stable) {
9585         enforceNotIsolatedCaller("removeContentProvider");
9586         long ident = Binder.clearCallingIdentity();
9587         try {
9588             synchronized (this) {
9589                 ContentProviderConnection conn;
9590                 try {
9591                     conn = (ContentProviderConnection)connection;
9592                 } catch (ClassCastException e) {
9593                     String msg ="removeContentProvider: " + connection
9594                             + " not a ContentProviderConnection";
9595                     Slog.w(TAG, msg);
9596                     throw new IllegalArgumentException(msg);
9597                 }
9598                 if (conn == null) {
9599                     throw new NullPointerException("connection is null");
9600                 }
9601                 if (decProviderCountLocked(conn, null, null, stable)) {
9602                     updateOomAdjLocked();
9603                 }
9604             }
9605         } finally {
9606             Binder.restoreCallingIdentity(ident);
9607         }
9608     }
9609
9610     public void removeContentProviderExternal(String name, IBinder token) {
9611         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9612             "Do not have permission in call removeContentProviderExternal()");
9613         int userId = UserHandle.getCallingUserId();
9614         long ident = Binder.clearCallingIdentity();
9615         try {
9616             removeContentProviderExternalUnchecked(name, token, userId);
9617         } finally {
9618             Binder.restoreCallingIdentity(ident);
9619         }
9620     }
9621
9622     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9623         synchronized (this) {
9624             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9625             if(cpr == null) {
9626                 //remove from mProvidersByClass
9627                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9628                 return;
9629             }
9630
9631             //update content provider record entry info
9632             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9633             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9634             if (localCpr.hasExternalProcessHandles()) {
9635                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9636                     updateOomAdjLocked();
9637                 } else {
9638                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9639                             + " with no external reference for token: "
9640                             + token + ".");
9641                 }
9642             } else {
9643                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9644                         + " with no external references.");
9645             }
9646         }
9647     }
9648     
9649     public final void publishContentProviders(IApplicationThread caller,
9650             List<ContentProviderHolder> providers) {
9651         if (providers == null) {
9652             return;
9653         }
9654
9655         enforceNotIsolatedCaller("publishContentProviders");
9656         synchronized (this) {
9657             final ProcessRecord r = getRecordForAppLocked(caller);
9658             if (DEBUG_MU)
9659                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9660             if (r == null) {
9661                 throw new SecurityException(
9662                         "Unable to find app for caller " + caller
9663                       + " (pid=" + Binder.getCallingPid()
9664                       + ") when publishing content providers");
9665             }
9666
9667             final long origId = Binder.clearCallingIdentity();
9668
9669             final int N = providers.size();
9670             for (int i=0; i<N; i++) {
9671                 ContentProviderHolder src = providers.get(i);
9672                 if (src == null || src.info == null || src.provider == null) {
9673                     continue;
9674                 }
9675                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9676                 if (DEBUG_MU)
9677                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9678                 if (dst != null) {
9679                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9680                     mProviderMap.putProviderByClass(comp, dst);
9681                     String names[] = dst.info.authority.split(";");
9682                     for (int j = 0; j < names.length; j++) {
9683                         mProviderMap.putProviderByName(names[j], dst);
9684                     }
9685
9686                     int NL = mLaunchingProviders.size();
9687                     int j;
9688                     for (j=0; j<NL; j++) {
9689                         if (mLaunchingProviders.get(j) == dst) {
9690                             mLaunchingProviders.remove(j);
9691                             j--;
9692                             NL--;
9693                         }
9694                     }
9695                     synchronized (dst) {
9696                         dst.provider = src.provider;
9697                         dst.proc = r;
9698                         dst.notifyAll();
9699                     }
9700                     updateOomAdjLocked(r);
9701                 }
9702             }
9703
9704             Binder.restoreCallingIdentity(origId);
9705         }
9706     }
9707
9708     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9709         ContentProviderConnection conn;
9710         try {
9711             conn = (ContentProviderConnection)connection;
9712         } catch (ClassCastException e) {
9713             String msg ="refContentProvider: " + connection
9714                     + " not a ContentProviderConnection";
9715             Slog.w(TAG, msg);
9716             throw new IllegalArgumentException(msg);
9717         }
9718         if (conn == null) {
9719             throw new NullPointerException("connection is null");
9720         }
9721
9722         synchronized (this) {
9723             if (stable > 0) {
9724                 conn.numStableIncs += stable;
9725             }
9726             stable = conn.stableCount + stable;
9727             if (stable < 0) {
9728                 throw new IllegalStateException("stableCount < 0: " + stable);
9729             }
9730
9731             if (unstable > 0) {
9732                 conn.numUnstableIncs += unstable;
9733             }
9734             unstable = conn.unstableCount + unstable;
9735             if (unstable < 0) {
9736                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9737             }
9738
9739             if ((stable+unstable) <= 0) {
9740                 throw new IllegalStateException("ref counts can't go to zero here: stable="
9741                         + stable + " unstable=" + unstable);
9742             }
9743             conn.stableCount = stable;
9744             conn.unstableCount = unstable;
9745             return !conn.dead;
9746         }
9747     }
9748
9749     public void unstableProviderDied(IBinder connection) {
9750         ContentProviderConnection conn;
9751         try {
9752             conn = (ContentProviderConnection)connection;
9753         } catch (ClassCastException e) {
9754             String msg ="refContentProvider: " + connection
9755                     + " not a ContentProviderConnection";
9756             Slog.w(TAG, msg);
9757             throw new IllegalArgumentException(msg);
9758         }
9759         if (conn == null) {
9760             throw new NullPointerException("connection is null");
9761         }
9762
9763         // Safely retrieve the content provider associated with the connection.
9764         IContentProvider provider;
9765         synchronized (this) {
9766             provider = conn.provider.provider;
9767         }
9768
9769         if (provider == null) {
9770             // Um, yeah, we're way ahead of you.
9771             return;
9772         }
9773
9774         // Make sure the caller is being honest with us.
9775         if (provider.asBinder().pingBinder()) {
9776             // Er, no, still looks good to us.
9777             synchronized (this) {
9778                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9779                         + " says " + conn + " died, but we don't agree");
9780                 return;
9781             }
9782         }
9783
9784         // Well look at that!  It's dead!
9785         synchronized (this) {
9786             if (conn.provider.provider != provider) {
9787                 // But something changed...  good enough.
9788                 return;
9789             }
9790
9791             ProcessRecord proc = conn.provider.proc;
9792             if (proc == null || proc.thread == null) {
9793                 // Seems like the process is already cleaned up.
9794                 return;
9795             }
9796
9797             // As far as we're concerned, this is just like receiving a
9798             // death notification...  just a bit prematurely.
9799             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9800                     + ") early provider death");
9801             final long ident = Binder.clearCallingIdentity();
9802             try {
9803                 appDiedLocked(proc);
9804             } finally {
9805                 Binder.restoreCallingIdentity(ident);
9806             }
9807         }
9808     }
9809
9810     @Override
9811     public void appNotRespondingViaProvider(IBinder connection) {
9812         enforceCallingPermission(
9813                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9814
9815         final ContentProviderConnection conn = (ContentProviderConnection) connection;
9816         if (conn == null) {
9817             Slog.w(TAG, "ContentProviderConnection is null");
9818             return;
9819         }
9820
9821         final ProcessRecord host = conn.provider.proc;
9822         if (host == null) {
9823             Slog.w(TAG, "Failed to find hosting ProcessRecord");
9824             return;
9825         }
9826
9827         final long token = Binder.clearCallingIdentity();
9828         try {
9829             appNotResponding(host, null, null, false, "ContentProvider not responding");
9830         } finally {
9831             Binder.restoreCallingIdentity(token);
9832         }
9833     }
9834
9835     public final void installSystemProviders() {
9836         List<ProviderInfo> providers;
9837         synchronized (this) {
9838             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9839             providers = generateApplicationProvidersLocked(app);
9840             if (providers != null) {
9841                 for (int i=providers.size()-1; i>=0; i--) {
9842                     ProviderInfo pi = (ProviderInfo)providers.get(i);
9843                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9844                         Slog.w(TAG, "Not installing system proc provider " + pi.name
9845                                 + ": not system .apk");
9846                         providers.remove(i);
9847                     }
9848                 }
9849             }
9850         }
9851         if (providers != null) {
9852             mSystemThread.installSystemProviders(providers);
9853         }
9854
9855         mCoreSettingsObserver = new CoreSettingsObserver(this);
9856
9857         //mUsageStatsService.monitorPackages();
9858     }
9859
9860     /**
9861      * Allows apps to retrieve the MIME type of a URI.
9862      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9863      * users, then it does not need permission to access the ContentProvider.
9864      * Either, it needs cross-user uri grants.
9865      *
9866      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9867      *
9868      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9869      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9870      */
9871     public String getProviderMimeType(Uri uri, int userId) {
9872         enforceNotIsolatedCaller("getProviderMimeType");
9873         final String name = uri.getAuthority();
9874         int callingUid = Binder.getCallingUid();
9875         int callingPid = Binder.getCallingPid();
9876         long ident = 0;
9877         boolean clearedIdentity = false;
9878         userId = unsafeConvertIncomingUser(userId);
9879         if (canClearIdentity(callingPid, callingUid, userId)) {
9880             clearedIdentity = true;
9881             ident = Binder.clearCallingIdentity();
9882         }
9883         ContentProviderHolder holder = null;
9884         try {
9885             holder = getContentProviderExternalUnchecked(name, null, userId);
9886             if (holder != null) {
9887                 return holder.provider.getType(uri);
9888             }
9889         } catch (RemoteException e) {
9890             Log.w(TAG, "Content provider dead retrieving " + uri, e);
9891             return null;
9892         } finally {
9893             // We need to clear the identity to call removeContentProviderExternalUnchecked
9894             if (!clearedIdentity) {
9895                 ident = Binder.clearCallingIdentity();
9896             }
9897             try {
9898                 if (holder != null) {
9899                     removeContentProviderExternalUnchecked(name, null, userId);
9900                 }
9901             } finally {
9902                 Binder.restoreCallingIdentity(ident);
9903             }
9904         }
9905
9906         return null;
9907     }
9908
9909     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9910         if (UserHandle.getUserId(callingUid) == userId) {
9911             return true;
9912         }
9913         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9914                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9915                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9916                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9917                 return true;
9918         }
9919         return false;
9920     }
9921
9922     // =========================================================
9923     // GLOBAL MANAGEMENT
9924     // =========================================================
9925
9926     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9927             boolean isolated, int isolatedUid) {
9928         String proc = customProcess != null ? customProcess : info.processName;
9929         BatteryStatsImpl.Uid.Proc ps = null;
9930         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9931         int uid = info.uid;
9932         if (isolated) {
9933             if (isolatedUid == 0) {
9934                 int userId = UserHandle.getUserId(uid);
9935                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9936                 while (true) {
9937                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9938                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9939                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9940                     }
9941                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9942                     mNextIsolatedProcessUid++;
9943                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9944                         // No process for this uid, use it.
9945                         break;
9946                     }
9947                     stepsLeft--;
9948                     if (stepsLeft <= 0) {
9949                         return null;
9950                     }
9951                 }
9952             } else {
9953                 // Special case for startIsolatedProcess (internal only), where
9954                 // the uid of the isolated process is specified by the caller.
9955                 uid = isolatedUid;
9956             }
9957         }
9958         return new ProcessRecord(stats, info, proc, uid);
9959     }
9960
9961     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9962             String abiOverride) {
9963         ProcessRecord app;
9964         if (!isolated) {
9965             app = getProcessRecordLocked(info.processName, info.uid, true);
9966         } else {
9967             app = null;
9968         }
9969
9970         if (app == null) {
9971             app = newProcessRecordLocked(info, null, isolated, 0);
9972             mProcessNames.put(info.processName, app.uid, app);
9973             if (isolated) {
9974                 mIsolatedProcesses.put(app.uid, app);
9975             }
9976             updateLruProcessLocked(app, false, null);
9977             updateOomAdjLocked();
9978         }
9979
9980         // This package really, really can not be stopped.
9981         try {
9982             AppGlobals.getPackageManager().setPackageStoppedState(
9983                     info.packageName, false, UserHandle.getUserId(app.uid));
9984         } catch (RemoteException e) {
9985         } catch (IllegalArgumentException e) {
9986             Slog.w(TAG, "Failed trying to unstop package "
9987                     + info.packageName + ": " + e);
9988         }
9989
9990         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9991                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9992             app.persistent = true;
9993             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9994         }
9995         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9996             mPersistentStartingProcesses.add(app);
9997             startProcessLocked(app, "added application", app.processName, abiOverride,
9998                     null /* entryPoint */, null /* entryPointArgs */);
9999         }
10000
10001         return app;
10002     }
10003
10004     public void unhandledBack() {
10005         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10006                 "unhandledBack()");
10007
10008         synchronized(this) {
10009             final long origId = Binder.clearCallingIdentity();
10010             try {
10011                 getFocusedStack().unhandledBackLocked();
10012             } finally {
10013                 Binder.restoreCallingIdentity(origId);
10014             }
10015         }
10016     }
10017
10018     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10019         enforceNotIsolatedCaller("openContentUri");
10020         final int userId = UserHandle.getCallingUserId();
10021         String name = uri.getAuthority();
10022         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10023         ParcelFileDescriptor pfd = null;
10024         if (cph != null) {
10025             // We record the binder invoker's uid in thread-local storage before
10026             // going to the content provider to open the file.  Later, in the code
10027             // that handles all permissions checks, we look for this uid and use
10028             // that rather than the Activity Manager's own uid.  The effect is that
10029             // we do the check against the caller's permissions even though it looks
10030             // to the content provider like the Activity Manager itself is making
10031             // the request.
10032             sCallerIdentity.set(new Identity(
10033                     Binder.getCallingPid(), Binder.getCallingUid()));
10034             try {
10035                 pfd = cph.provider.openFile(null, uri, "r", null);
10036             } catch (FileNotFoundException e) {
10037                 // do nothing; pfd will be returned null
10038             } finally {
10039                 // Ensure that whatever happens, we clean up the identity state
10040                 sCallerIdentity.remove();
10041             }
10042
10043             // We've got the fd now, so we're done with the provider.
10044             removeContentProviderExternalUnchecked(name, null, userId);
10045         } else {
10046             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10047         }
10048         return pfd;
10049     }
10050
10051     // Actually is sleeping or shutting down or whatever else in the future
10052     // is an inactive state.
10053     public boolean isSleepingOrShuttingDown() {
10054         return isSleeping() || mShuttingDown;
10055     }
10056
10057     public boolean isSleeping() {
10058         return mSleeping;
10059     }
10060
10061     void onWakefulnessChanged(int wakefulness) {
10062         synchronized(this) {
10063             mWakefulness = wakefulness;
10064             updateSleepIfNeededLocked();
10065         }
10066     }
10067
10068     void finishRunningVoiceLocked() {
10069         if (mRunningVoice) {
10070             mRunningVoice = false;
10071             updateSleepIfNeededLocked();
10072         }
10073     }
10074
10075     void updateSleepIfNeededLocked() {
10076         if (mSleeping && !shouldSleepLocked()) {
10077             mSleeping = false;
10078             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10079         } else if (!mSleeping && shouldSleepLocked()) {
10080             mSleeping = true;
10081             mStackSupervisor.goingToSleepLocked();
10082
10083             // Initialize the wake times of all processes.
10084             checkExcessivePowerUsageLocked(false);
10085             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10086             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10087             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10088         }
10089     }
10090
10091     private boolean shouldSleepLocked() {
10092         // Resume applications while running a voice interactor.
10093         if (mRunningVoice) {
10094             return false;
10095         }
10096
10097         switch (mWakefulness) {
10098             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10099             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10100                 // If we're interactive but applications are already paused then defer
10101                 // resuming them until the lock screen is hidden.
10102                 return mSleeping && mLockScreenShown;
10103             case PowerManagerInternal.WAKEFULNESS_DOZING:
10104                 // If we're dozing then pause applications whenever the lock screen is shown.
10105                 return mLockScreenShown;
10106             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10107             default:
10108                 // If we're asleep then pause applications unconditionally.
10109                 return true;
10110         }
10111     }
10112
10113     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10114         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10115             // Never persist the home stack.
10116             return;
10117         }
10118         mTaskPersister.wakeup(task, flush);
10119     }
10120
10121     @Override
10122     public boolean shutdown(int timeout) {
10123         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10124                 != PackageManager.PERMISSION_GRANTED) {
10125             throw new SecurityException("Requires permission "
10126                     + android.Manifest.permission.SHUTDOWN);
10127         }
10128
10129         boolean timedout = false;
10130
10131         synchronized(this) {
10132             mShuttingDown = true;
10133             updateEventDispatchingLocked();
10134             timedout = mStackSupervisor.shutdownLocked(timeout);
10135         }
10136
10137         mAppOpsService.shutdown();
10138         if (mUsageStatsService != null) {
10139             mUsageStatsService.prepareShutdown();
10140         }
10141         mBatteryStatsService.shutdown();
10142         synchronized (this) {
10143             mProcessStats.shutdownLocked();
10144         }
10145         notifyTaskPersisterLocked(null, true);
10146
10147         return timedout;
10148     }
10149     
10150     public final void activitySlept(IBinder token) {
10151         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10152
10153         final long origId = Binder.clearCallingIdentity();
10154
10155         synchronized (this) {
10156             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10157             if (r != null) {
10158                 mStackSupervisor.activitySleptLocked(r);
10159             }
10160         }
10161
10162         Binder.restoreCallingIdentity(origId);
10163     }
10164
10165     void logLockScreen(String msg) {
10166         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10167                 + " mLockScreenShown=" + mLockScreenShown + " mWakefulness="
10168                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10169                 + " mSleeping=" + mSleeping);
10170     }
10171
10172     void startRunningVoiceLocked() {
10173         if (!mRunningVoice) {
10174             mRunningVoice = true;
10175             updateSleepIfNeededLocked();
10176         }
10177     }
10178
10179     private void updateEventDispatchingLocked() {
10180         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10181     }
10182
10183     public void setLockScreenShown(boolean shown) {
10184         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10185                 != PackageManager.PERMISSION_GRANTED) {
10186             throw new SecurityException("Requires permission "
10187                     + android.Manifest.permission.DEVICE_POWER);
10188         }
10189
10190         synchronized(this) {
10191             long ident = Binder.clearCallingIdentity();
10192             try {
10193                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10194                 mLockScreenShown = shown;
10195                 updateSleepIfNeededLocked();
10196             } finally {
10197                 Binder.restoreCallingIdentity(ident);
10198             }
10199         }
10200     }
10201
10202     @Override
10203     public void stopAppSwitches() {
10204         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10205                 != PackageManager.PERMISSION_GRANTED) {
10206             throw new SecurityException("Requires permission "
10207                     + android.Manifest.permission.STOP_APP_SWITCHES);
10208         }
10209         
10210         synchronized(this) {
10211             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10212                     + APP_SWITCH_DELAY_TIME;
10213             mDidAppSwitch = false;
10214             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10215             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10216             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10217         }
10218     }
10219     
10220     public void resumeAppSwitches() {
10221         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10222                 != PackageManager.PERMISSION_GRANTED) {
10223             throw new SecurityException("Requires permission "
10224                     + android.Manifest.permission.STOP_APP_SWITCHES);
10225         }
10226         
10227         synchronized(this) {
10228             // Note that we don't execute any pending app switches... we will
10229             // let those wait until either the timeout, or the next start
10230             // activity request.
10231             mAppSwitchesAllowedTime = 0;
10232         }
10233     }
10234     
10235     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10236             int callingPid, int callingUid, String name) {
10237         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10238             return true;
10239         }
10240
10241         int perm = checkComponentPermission(
10242                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10243                 sourceUid, -1, true);
10244         if (perm == PackageManager.PERMISSION_GRANTED) {
10245             return true;
10246         }
10247
10248         // If the actual IPC caller is different from the logical source, then
10249         // also see if they are allowed to control app switches.
10250         if (callingUid != -1 && callingUid != sourceUid) {
10251             perm = checkComponentPermission(
10252                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10253                     callingUid, -1, true);
10254             if (perm == PackageManager.PERMISSION_GRANTED) {
10255                 return true;
10256             }
10257         }
10258
10259         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10260         return false;
10261     }
10262     
10263     public void setDebugApp(String packageName, boolean waitForDebugger,
10264             boolean persistent) {
10265         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10266                 "setDebugApp()");
10267
10268         long ident = Binder.clearCallingIdentity();
10269         try {
10270             // Note that this is not really thread safe if there are multiple
10271             // callers into it at the same time, but that's not a situation we
10272             // care about.
10273             if (persistent) {
10274                 final ContentResolver resolver = mContext.getContentResolver();
10275                 Settings.Global.putString(
10276                     resolver, Settings.Global.DEBUG_APP,
10277                     packageName);
10278                 Settings.Global.putInt(
10279                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10280                     waitForDebugger ? 1 : 0);
10281             }
10282
10283             synchronized (this) {
10284                 if (!persistent) {
10285                     mOrigDebugApp = mDebugApp;
10286                     mOrigWaitForDebugger = mWaitForDebugger;
10287                 }
10288                 mDebugApp = packageName;
10289                 mWaitForDebugger = waitForDebugger;
10290                 mDebugTransient = !persistent;
10291                 if (packageName != null) {
10292                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10293                             false, UserHandle.USER_ALL, "set debug app");
10294                 }
10295             }
10296         } finally {
10297             Binder.restoreCallingIdentity(ident);
10298         }
10299     }
10300
10301     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10302         synchronized (this) {
10303             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10304             if (!isDebuggable) {
10305                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10306                     throw new SecurityException("Process not debuggable: " + app.packageName);
10307                 }
10308             }
10309
10310             mOpenGlTraceApp = processName;
10311         }
10312     }
10313
10314     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10315         synchronized (this) {
10316             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10317             if (!isDebuggable) {
10318                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10319                     throw new SecurityException("Process not debuggable: " + app.packageName);
10320                 }
10321             }
10322             mProfileApp = processName;
10323             mProfileFile = profilerInfo.profileFile;
10324             if (mProfileFd != null) {
10325                 try {
10326                     mProfileFd.close();
10327                 } catch (IOException e) {
10328                 }
10329                 mProfileFd = null;
10330             }
10331             mProfileFd = profilerInfo.profileFd;
10332             mSamplingInterval = profilerInfo.samplingInterval;
10333             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10334             mProfileType = 0;
10335         }
10336     }
10337
10338     @Override
10339     public void setAlwaysFinish(boolean enabled) {
10340         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10341                 "setAlwaysFinish()");
10342
10343         Settings.Global.putInt(
10344                 mContext.getContentResolver(),
10345                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10346
10347         synchronized (this) {
10348             mAlwaysFinishActivities = enabled;
10349         }
10350     }
10351
10352     @Override
10353     public void setActivityController(IActivityController controller) {
10354         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10355                 "setActivityController()");
10356         synchronized (this) {
10357             mController = controller;
10358             Watchdog.getInstance().setActivityController(controller);
10359         }
10360     }
10361
10362     @Override
10363     public void setUserIsMonkey(boolean userIsMonkey) {
10364         synchronized (this) {
10365             synchronized (mPidsSelfLocked) {
10366                 final int callingPid = Binder.getCallingPid();
10367                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10368                 if (precessRecord == null) {
10369                     throw new SecurityException("Unknown process: " + callingPid);
10370                 }
10371                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10372                     throw new SecurityException("Only an instrumentation process "
10373                             + "with a UiAutomation can call setUserIsMonkey");
10374                 }
10375             }
10376             mUserIsMonkey = userIsMonkey;
10377         }
10378     }
10379
10380     @Override
10381     public boolean isUserAMonkey() {
10382         synchronized (this) {
10383             // If there is a controller also implies the user is a monkey.
10384             return (mUserIsMonkey || mController != null);
10385         }
10386     }
10387
10388     public void requestBugReport() {
10389         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10390         SystemProperties.set("ctl.start", "bugreport");
10391     }
10392
10393     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10394         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10395     }
10396
10397     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10398         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10399             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10400         }
10401         return KEY_DISPATCHING_TIMEOUT;
10402     }
10403
10404     @Override
10405     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10406         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10407                 != PackageManager.PERMISSION_GRANTED) {
10408             throw new SecurityException("Requires permission "
10409                     + android.Manifest.permission.FILTER_EVENTS);
10410         }
10411         ProcessRecord proc;
10412         long timeout;
10413         synchronized (this) {
10414             synchronized (mPidsSelfLocked) {
10415                 proc = mPidsSelfLocked.get(pid);
10416             }
10417             timeout = getInputDispatchingTimeoutLocked(proc);
10418         }
10419
10420         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10421             return -1;
10422         }
10423
10424         return timeout;
10425     }
10426
10427     /**
10428      * Handle input dispatching timeouts.
10429      * Returns whether input dispatching should be aborted or not.
10430      */
10431     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10432             final ActivityRecord activity, final ActivityRecord parent,
10433             final boolean aboveSystem, String reason) {
10434         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10435                 != PackageManager.PERMISSION_GRANTED) {
10436             throw new SecurityException("Requires permission "
10437                     + android.Manifest.permission.FILTER_EVENTS);
10438         }
10439
10440         final String annotation;
10441         if (reason == null) {
10442             annotation = "Input dispatching timed out";
10443         } else {
10444             annotation = "Input dispatching timed out (" + reason + ")";
10445         }
10446
10447         if (proc != null) {
10448             synchronized (this) {
10449                 if (proc.debugging) {
10450                     return false;
10451                 }
10452
10453                 if (mDidDexOpt) {
10454                     // Give more time since we were dexopting.
10455                     mDidDexOpt = false;
10456                     return false;
10457                 }
10458
10459                 if (proc.instrumentationClass != null) {
10460                     Bundle info = new Bundle();
10461                     info.putString("shortMsg", "keyDispatchingTimedOut");
10462                     info.putString("longMsg", annotation);
10463                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10464                     return true;
10465                 }
10466             }
10467             mHandler.post(new Runnable() {
10468                 @Override
10469                 public void run() {
10470                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10471                 }
10472             });
10473         }
10474
10475         return true;
10476     }
10477
10478     public Bundle getAssistContextExtras(int requestType) {
10479         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10480                 UserHandle.getCallingUserId());
10481         if (pae == null) {
10482             return null;
10483         }
10484         synchronized (pae) {
10485             while (!pae.haveResult) {
10486                 try {
10487                     pae.wait();
10488                 } catch (InterruptedException e) {
10489                 }
10490             }
10491             if (pae.result != null) {
10492                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10493             }
10494         }
10495         synchronized (this) {
10496             mPendingAssistExtras.remove(pae);
10497             mHandler.removeCallbacks(pae);
10498         }
10499         return pae.extras;
10500     }
10501
10502     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10503             int userHandle) {
10504         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10505                 "getAssistContextExtras()");
10506         PendingAssistExtras pae;
10507         Bundle extras = new Bundle();
10508         synchronized (this) {
10509             ActivityRecord activity = getFocusedStack().mResumedActivity;
10510             if (activity == null) {
10511                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10512                 return null;
10513             }
10514             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10515             if (activity.app == null || activity.app.thread == null) {
10516                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10517                 return null;
10518             }
10519             if (activity.app.pid == Binder.getCallingPid()) {
10520                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10521                 return null;
10522             }
10523             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10524             try {
10525                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10526                         requestType);
10527                 mPendingAssistExtras.add(pae);
10528                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10529             } catch (RemoteException e) {
10530                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10531                 return null;
10532             }
10533             return pae;
10534         }
10535     }
10536
10537     public void reportAssistContextExtras(IBinder token, Bundle extras) {
10538         PendingAssistExtras pae = (PendingAssistExtras)token;
10539         synchronized (pae) {
10540             pae.result = extras;
10541             pae.haveResult = true;
10542             pae.notifyAll();
10543             if (pae.intent == null) {
10544                 // Caller is just waiting for the result.
10545                 return;
10546             }
10547         }
10548
10549         // We are now ready to launch the assist activity.
10550         synchronized (this) {
10551             boolean exists = mPendingAssistExtras.remove(pae);
10552             mHandler.removeCallbacks(pae);
10553             if (!exists) {
10554                 // Timed out.
10555                 return;
10556             }
10557         }
10558         pae.intent.replaceExtras(extras);
10559         if (pae.hint != null) {
10560             pae.intent.putExtra(pae.hint, true);
10561         }
10562         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10563                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10564                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10565         closeSystemDialogs("assist");
10566         try {
10567             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10568         } catch (ActivityNotFoundException e) {
10569             Slog.w(TAG, "No activity to handle assist action.", e);
10570         }
10571     }
10572
10573     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10574         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10575     }
10576
10577     public void registerProcessObserver(IProcessObserver observer) {
10578         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10579                 "registerProcessObserver()");
10580         synchronized (this) {
10581             mProcessObservers.register(observer);
10582         }
10583     }
10584
10585     @Override
10586     public void unregisterProcessObserver(IProcessObserver observer) {
10587         synchronized (this) {
10588             mProcessObservers.unregister(observer);
10589         }
10590     }
10591
10592     @Override
10593     public boolean convertFromTranslucent(IBinder token) {
10594         final long origId = Binder.clearCallingIdentity();
10595         try {
10596             synchronized (this) {
10597                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10598                 if (r == null) {
10599                     return false;
10600                 }
10601                 final boolean translucentChanged = r.changeWindowTranslucency(true);
10602                 if (translucentChanged) {
10603                     r.task.stack.releaseBackgroundResources();
10604                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10605                 }
10606                 mWindowManager.setAppFullscreen(token, true);
10607                 return translucentChanged;
10608             }
10609         } finally {
10610             Binder.restoreCallingIdentity(origId);
10611         }
10612     }
10613
10614     @Override
10615     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10616         final long origId = Binder.clearCallingIdentity();
10617         try {
10618             synchronized (this) {
10619                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10620                 if (r == null) {
10621                     return false;
10622                 }
10623                 int index = r.task.mActivities.lastIndexOf(r);
10624                 if (index > 0) {
10625                     ActivityRecord under = r.task.mActivities.get(index - 1);
10626                     under.returningOptions = options;
10627                 }
10628                 final boolean translucentChanged = r.changeWindowTranslucency(false);
10629                 if (translucentChanged) {
10630                     r.task.stack.convertToTranslucent(r);
10631                 }
10632                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10633                 mWindowManager.setAppFullscreen(token, false);
10634                 return translucentChanged;
10635             }
10636         } finally {
10637             Binder.restoreCallingIdentity(origId);
10638         }
10639     }
10640
10641     @Override
10642     public boolean requestVisibleBehind(IBinder token, boolean visible) {
10643         final long origId = Binder.clearCallingIdentity();
10644         try {
10645             synchronized (this) {
10646                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10647                 if (r != null) {
10648                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10649                 }
10650             }
10651             return false;
10652         } finally {
10653             Binder.restoreCallingIdentity(origId);
10654         }
10655     }
10656
10657     @Override
10658     public boolean isBackgroundVisibleBehind(IBinder token) {
10659         final long origId = Binder.clearCallingIdentity();
10660         try {
10661             synchronized (this) {
10662                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10663                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10664                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10665                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10666                 return visible;
10667             }
10668         } finally {
10669             Binder.restoreCallingIdentity(origId);
10670         }
10671     }
10672
10673     @Override
10674     public ActivityOptions getActivityOptions(IBinder token) {
10675         final long origId = Binder.clearCallingIdentity();
10676         try {
10677             synchronized (this) {
10678                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10679                 if (r != null) {
10680                     final ActivityOptions activityOptions = r.pendingOptions;
10681                     r.pendingOptions = null;
10682                     return activityOptions;
10683                 }
10684                 return null;
10685             }
10686         } finally {
10687             Binder.restoreCallingIdentity(origId);
10688         }
10689     }
10690
10691     @Override
10692     public void setImmersive(IBinder token, boolean immersive) {
10693         synchronized(this) {
10694             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10695             if (r == null) {
10696                 throw new IllegalArgumentException();
10697             }
10698             r.immersive = immersive;
10699
10700             // update associated state if we're frontmost
10701             if (r == mFocusedActivity) {
10702                 if (DEBUG_IMMERSIVE) {
10703                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
10704                 }
10705                 applyUpdateLockStateLocked(r);
10706             }
10707         }
10708     }
10709
10710     @Override
10711     public boolean isImmersive(IBinder token) {
10712         synchronized (this) {
10713             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10714             if (r == null) {
10715                 throw new IllegalArgumentException();
10716             }
10717             return r.immersive;
10718         }
10719     }
10720
10721     public boolean isTopActivityImmersive() {
10722         enforceNotIsolatedCaller("startActivity");
10723         synchronized (this) {
10724             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10725             return (r != null) ? r.immersive : false;
10726         }
10727     }
10728
10729     @Override
10730     public boolean isTopOfTask(IBinder token) {
10731         synchronized (this) {
10732             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10733             if (r == null) {
10734                 throw new IllegalArgumentException();
10735             }
10736             return r.task.getTopActivity() == r;
10737         }
10738     }
10739
10740     public final void enterSafeMode() {
10741         synchronized(this) {
10742             // It only makes sense to do this before the system is ready
10743             // and started launching other packages.
10744             if (!mSystemReady) {
10745                 try {
10746                     AppGlobals.getPackageManager().enterSafeMode();
10747                 } catch (RemoteException e) {
10748                 }
10749             }
10750
10751             mSafeMode = true;
10752         }
10753     }
10754
10755     public final void showSafeModeOverlay() {
10756         View v = LayoutInflater.from(mContext).inflate(
10757                 com.android.internal.R.layout.safe_mode, null);
10758         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10759         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10760         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10761         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10762         lp.gravity = Gravity.BOTTOM | Gravity.START;
10763         lp.format = v.getBackground().getOpacity();
10764         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10765                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10766         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10767         ((WindowManager)mContext.getSystemService(
10768                 Context.WINDOW_SERVICE)).addView(v, lp);
10769     }
10770
10771     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10772         if (!(sender instanceof PendingIntentRecord)) {
10773             return;
10774         }
10775         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10776         synchronized (stats) {
10777             if (mBatteryStatsService.isOnBattery()) {
10778                 mBatteryStatsService.enforceCallingPermission();
10779                 PendingIntentRecord rec = (PendingIntentRecord)sender;
10780                 int MY_UID = Binder.getCallingUid();
10781                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10782                 BatteryStatsImpl.Uid.Pkg pkg =
10783                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10784                             sourcePkg != null ? sourcePkg : rec.key.packageName);
10785                 pkg.incWakeupsLocked();
10786             }
10787         }
10788     }
10789
10790     public boolean killPids(int[] pids, String pReason, boolean secure) {
10791         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10792             throw new SecurityException("killPids only available to the system");
10793         }
10794         String reason = (pReason == null) ? "Unknown" : pReason;
10795         // XXX Note: don't acquire main activity lock here, because the window
10796         // manager calls in with its locks held.
10797
10798         boolean killed = false;
10799         synchronized (mPidsSelfLocked) {
10800             int[] types = new int[pids.length];
10801             int worstType = 0;
10802             for (int i=0; i<pids.length; i++) {
10803                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10804                 if (proc != null) {
10805                     int type = proc.setAdj;
10806                     types[i] = type;
10807                     if (type > worstType) {
10808                         worstType = type;
10809                     }
10810                 }
10811             }
10812
10813             // If the worst oom_adj is somewhere in the cached proc LRU range,
10814             // then constrain it so we will kill all cached procs.
10815             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10816                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10817                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10818             }
10819
10820             // If this is not a secure call, don't let it kill processes that
10821             // are important.
10822             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10823                 worstType = ProcessList.SERVICE_ADJ;
10824             }
10825
10826             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10827             for (int i=0; i<pids.length; i++) {
10828                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10829                 if (proc == null) {
10830                     continue;
10831                 }
10832                 int adj = proc.setAdj;
10833                 if (adj >= worstType && !proc.killedByAm) {
10834                     proc.kill(reason, true);
10835                     killed = true;
10836                 }
10837             }
10838         }
10839         return killed;
10840     }
10841
10842     @Override
10843     public void killUid(int uid, String reason) {
10844         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10845             throw new SecurityException("killUid only available to the system");
10846         }
10847         synchronized (this) {
10848             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10849                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10850                     reason != null ? reason : "kill uid");
10851         }
10852     }
10853
10854     @Override
10855     public boolean killProcessesBelowForeground(String reason) {
10856         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10857             throw new SecurityException("killProcessesBelowForeground() only available to system");
10858         }
10859
10860         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10861     }
10862
10863     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10864         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10865             throw new SecurityException("killProcessesBelowAdj() only available to system");
10866         }
10867
10868         boolean killed = false;
10869         synchronized (mPidsSelfLocked) {
10870             final int size = mPidsSelfLocked.size();
10871             for (int i = 0; i < size; i++) {
10872                 final int pid = mPidsSelfLocked.keyAt(i);
10873                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10874                 if (proc == null) continue;
10875
10876                 final int adj = proc.setAdj;
10877                 if (adj > belowAdj && !proc.killedByAm) {
10878                     proc.kill(reason, true);
10879                     killed = true;
10880                 }
10881             }
10882         }
10883         return killed;
10884     }
10885
10886     @Override
10887     public void hang(final IBinder who, boolean allowRestart) {
10888         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10889                 != PackageManager.PERMISSION_GRANTED) {
10890             throw new SecurityException("Requires permission "
10891                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10892         }
10893
10894         final IBinder.DeathRecipient death = new DeathRecipient() {
10895             @Override
10896             public void binderDied() {
10897                 synchronized (this) {
10898                     notifyAll();
10899                 }
10900             }
10901         };
10902
10903         try {
10904             who.linkToDeath(death, 0);
10905         } catch (RemoteException e) {
10906             Slog.w(TAG, "hang: given caller IBinder is already dead.");
10907             return;
10908         }
10909
10910         synchronized (this) {
10911             Watchdog.getInstance().setAllowRestart(allowRestart);
10912             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10913             synchronized (death) {
10914                 while (who.isBinderAlive()) {
10915                     try {
10916                         death.wait();
10917                     } catch (InterruptedException e) {
10918                     }
10919                 }
10920             }
10921             Watchdog.getInstance().setAllowRestart(true);
10922         }
10923     }
10924
10925     @Override
10926     public void restart() {
10927         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10928                 != PackageManager.PERMISSION_GRANTED) {
10929             throw new SecurityException("Requires permission "
10930                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10931         }
10932
10933         Log.i(TAG, "Sending shutdown broadcast...");
10934
10935         BroadcastReceiver br = new BroadcastReceiver() {
10936             @Override public void onReceive(Context context, Intent intent) {
10937                 // Now the broadcast is done, finish up the low-level shutdown.
10938                 Log.i(TAG, "Shutting down activity manager...");
10939                 shutdown(10000);
10940                 Log.i(TAG, "Shutdown complete, restarting!");
10941                 Process.killProcess(Process.myPid());
10942                 System.exit(10);
10943             }
10944         };
10945
10946         // First send the high-level shut down broadcast.
10947         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10948         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10949         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10950         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10951         mContext.sendOrderedBroadcastAsUser(intent,
10952                 UserHandle.ALL, null, br, mHandler, 0, null, null);
10953         */
10954         br.onReceive(mContext, intent);
10955     }
10956
10957     private long getLowRamTimeSinceIdle(long now) {
10958         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10959     }
10960
10961     @Override
10962     public void performIdleMaintenance() {
10963         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10964                 != PackageManager.PERMISSION_GRANTED) {
10965             throw new SecurityException("Requires permission "
10966                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10967         }
10968
10969         synchronized (this) {
10970             final long now = SystemClock.uptimeMillis();
10971             final long timeSinceLastIdle = now - mLastIdleTime;
10972             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10973             mLastIdleTime = now;
10974             mLowRamTimeSinceLastIdle = 0;
10975             if (mLowRamStartTime != 0) {
10976                 mLowRamStartTime = now;
10977             }
10978
10979             StringBuilder sb = new StringBuilder(128);
10980             sb.append("Idle maintenance over ");
10981             TimeUtils.formatDuration(timeSinceLastIdle, sb);
10982             sb.append(" low RAM for ");
10983             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10984             Slog.i(TAG, sb.toString());
10985
10986             // If at least 1/3 of our time since the last idle period has been spent
10987             // with RAM low, then we want to kill processes.
10988             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10989
10990             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10991                 ProcessRecord proc = mLruProcesses.get(i);
10992                 if (proc.notCachedSinceIdle) {
10993                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10994                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10995                         if (doKilling && proc.initialIdlePss != 0
10996                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10997                             proc.kill("idle maint (pss " + proc.lastPss
10998                                     + " from " + proc.initialIdlePss + ")", true);
10999                         }
11000                     }
11001                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11002                     proc.notCachedSinceIdle = true;
11003                     proc.initialIdlePss = 0;
11004                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11005                             isSleeping(), now);
11006                 }
11007             }
11008
11009             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11010             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11011         }
11012     }
11013
11014     private void retrieveSettings() {
11015         final ContentResolver resolver = mContext.getContentResolver();
11016         String debugApp = Settings.Global.getString(
11017             resolver, Settings.Global.DEBUG_APP);
11018         boolean waitForDebugger = Settings.Global.getInt(
11019             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11020         boolean alwaysFinishActivities = Settings.Global.getInt(
11021             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11022         boolean forceRtl = Settings.Global.getInt(
11023                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11024         // Transfer any global setting for forcing RTL layout, into a System Property
11025         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11026
11027         Configuration configuration = new Configuration();
11028         Settings.System.getConfiguration(resolver, configuration);
11029         if (forceRtl) {
11030             // This will take care of setting the correct layout direction flags
11031             configuration.setLayoutDirection(configuration.locale);
11032         }
11033
11034         synchronized (this) {
11035             mDebugApp = mOrigDebugApp = debugApp;
11036             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11037             mAlwaysFinishActivities = alwaysFinishActivities;
11038             // This happens before any activities are started, so we can
11039             // change mConfiguration in-place.
11040             updateConfigurationLocked(configuration, null, false, true);
11041             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11042         }
11043     }
11044
11045     /** Loads resources after the current configuration has been set. */
11046     private void loadResourcesOnSystemReady() {
11047         final Resources res = mContext.getResources();
11048         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11049         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11050         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11051     }
11052
11053     public boolean testIsSystemReady() {
11054         // no need to synchronize(this) just to read & return the value
11055         return mSystemReady;
11056     }
11057
11058     private static File getCalledPreBootReceiversFile() {
11059         File dataDir = Environment.getDataDirectory();
11060         File systemDir = new File(dataDir, "system");
11061         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11062         return fname;
11063     }
11064
11065     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11066         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11067         File file = getCalledPreBootReceiversFile();
11068         FileInputStream fis = null;
11069         try {
11070             fis = new FileInputStream(file);
11071             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11072             int fvers = dis.readInt();
11073             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11074                 String vers = dis.readUTF();
11075                 String codename = dis.readUTF();
11076                 String build = dis.readUTF();
11077                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11078                         && android.os.Build.VERSION.CODENAME.equals(codename)
11079                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11080                     int num = dis.readInt();
11081                     while (num > 0) {
11082                         num--;
11083                         String pkg = dis.readUTF();
11084                         String cls = dis.readUTF();
11085                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11086                     }
11087                 }
11088             }
11089         } catch (FileNotFoundException e) {
11090         } catch (IOException e) {
11091             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11092         } finally {
11093             if (fis != null) {
11094                 try {
11095                     fis.close();
11096                 } catch (IOException e) {
11097                 }
11098             }
11099         }
11100         return lastDoneReceivers;
11101     }
11102
11103     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11104         File file = getCalledPreBootReceiversFile();
11105         FileOutputStream fos = null;
11106         DataOutputStream dos = null;
11107         try {
11108             fos = new FileOutputStream(file);
11109             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11110             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11111             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11112             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11113             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11114             dos.writeInt(list.size());
11115             for (int i=0; i<list.size(); i++) {
11116                 dos.writeUTF(list.get(i).getPackageName());
11117                 dos.writeUTF(list.get(i).getClassName());
11118             }
11119         } catch (IOException e) {
11120             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11121             file.delete();
11122         } finally {
11123             FileUtils.sync(fos);
11124             if (dos != null) {
11125                 try {
11126                     dos.close();
11127                 } catch (IOException e) {
11128                     // TODO Auto-generated catch block
11129                     e.printStackTrace();
11130                 }
11131             }
11132         }
11133     }
11134
11135     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11136             ArrayList<ComponentName> doneReceivers, int userId) {
11137         boolean waitingUpdate = false;
11138         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11139         List<ResolveInfo> ris = null;
11140         try {
11141             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11142                     intent, null, 0, userId);
11143         } catch (RemoteException e) {
11144         }
11145         if (ris != null) {
11146             for (int i=ris.size()-1; i>=0; i--) {
11147                 if ((ris.get(i).activityInfo.applicationInfo.flags
11148                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
11149                     ris.remove(i);
11150                 }
11151             }
11152             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11153
11154             // For User 0, load the version number. When delivering to a new user, deliver
11155             // to all receivers.
11156             if (userId == UserHandle.USER_OWNER) {
11157                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11158                 for (int i=0; i<ris.size(); i++) {
11159                     ActivityInfo ai = ris.get(i).activityInfo;
11160                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
11161                     if (lastDoneReceivers.contains(comp)) {
11162                         // We already did the pre boot receiver for this app with the current
11163                         // platform version, so don't do it again...
11164                         ris.remove(i);
11165                         i--;
11166                         // ...however, do keep it as one that has been done, so we don't
11167                         // forget about it when rewriting the file of last done receivers.
11168                         doneReceivers.add(comp);
11169                     }
11170                 }
11171             }
11172
11173             // If primary user, send broadcast to all available users, else just to userId
11174             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11175                     : new int[] { userId };
11176             for (int i = 0; i < ris.size(); i++) {
11177                 ActivityInfo ai = ris.get(i).activityInfo;
11178                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11179                 doneReceivers.add(comp);
11180                 intent.setComponent(comp);
11181                 for (int j=0; j<users.length; j++) {
11182                     IIntentReceiver finisher = null;
11183                     // On last receiver and user, set up a completion callback
11184                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11185                         finisher = new IIntentReceiver.Stub() {
11186                             public void performReceive(Intent intent, int resultCode,
11187                                     String data, Bundle extras, boolean ordered,
11188                                     boolean sticky, int sendingUser) {
11189                                 // The raw IIntentReceiver interface is called
11190                                 // with the AM lock held, so redispatch to
11191                                 // execute our code without the lock.
11192                                 mHandler.post(onFinishCallback);
11193                             }
11194                         };
11195                     }
11196                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
11197                             + " for user " + users[j]);
11198                     broadcastIntentLocked(null, null, intent, null, finisher,
11199                             0, null, null, null, AppOpsManager.OP_NONE,
11200                             true, false, MY_PID, Process.SYSTEM_UID,
11201                             users[j]);
11202                     if (finisher != null) {
11203                         waitingUpdate = true;
11204                     }
11205                 }
11206             }
11207         }
11208
11209         return waitingUpdate;
11210     }
11211
11212     public void systemReady(final Runnable goingCallback) {
11213         synchronized(this) {
11214             if (mSystemReady) {
11215                 // If we're done calling all the receivers, run the next "boot phase" passed in
11216                 // by the SystemServer
11217                 if (goingCallback != null) {
11218                     goingCallback.run();
11219                 }
11220                 return;
11221             }
11222
11223             // Make sure we have the current profile info, since it is needed for
11224             // security checks.
11225             updateCurrentProfileIdsLocked();
11226
11227             if (mRecentTasks == null) {
11228                 mRecentTasks = mTaskPersister.restoreTasksLocked();
11229                 if (!mRecentTasks.isEmpty()) {
11230                     mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11231                 }
11232                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11233                 mTaskPersister.startPersisting();
11234             }
11235
11236             // Check to see if there are any update receivers to run.
11237             if (!mDidUpdate) {
11238                 if (mWaitingUpdate) {
11239                     return;
11240                 }
11241                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11242                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11243                     public void run() {
11244                         synchronized (ActivityManagerService.this) {
11245                             mDidUpdate = true;
11246                         }
11247                         writeLastDonePreBootReceivers(doneReceivers);
11248                         showBootMessage(mContext.getText(
11249                                 R.string.android_upgrading_complete),
11250                                 false);
11251                         systemReady(goingCallback);
11252                     }
11253                 }, doneReceivers, UserHandle.USER_OWNER);
11254
11255                 if (mWaitingUpdate) {
11256                     return;
11257                 }
11258                 mDidUpdate = true;
11259             }
11260
11261             mAppOpsService.systemReady();
11262             mSystemReady = true;
11263         }
11264
11265         ArrayList<ProcessRecord> procsToKill = null;
11266         synchronized(mPidsSelfLocked) {
11267             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11268                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11269                 if (!isAllowedWhileBooting(proc.info)){
11270                     if (procsToKill == null) {
11271                         procsToKill = new ArrayList<ProcessRecord>();
11272                     }
11273                     procsToKill.add(proc);
11274                 }
11275             }
11276         }
11277         
11278         synchronized(this) {
11279             if (procsToKill != null) {
11280                 for (int i=procsToKill.size()-1; i>=0; i--) {
11281                     ProcessRecord proc = procsToKill.get(i);
11282                     Slog.i(TAG, "Removing system update proc: " + proc);
11283                     removeProcessLocked(proc, true, false, "system update done");
11284                 }
11285             }
11286             
11287             // Now that we have cleaned up any update processes, we
11288             // are ready to start launching real processes and know that
11289             // we won't trample on them any more.
11290             mProcessesReady = true;
11291         }
11292         
11293         Slog.i(TAG, "System now ready");
11294         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11295             SystemClock.uptimeMillis());
11296
11297         synchronized(this) {
11298             // Make sure we have no pre-ready processes sitting around.
11299             
11300             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11301                 ResolveInfo ri = mContext.getPackageManager()
11302                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11303                                 STOCK_PM_FLAGS);
11304                 CharSequence errorMsg = null;
11305                 if (ri != null) {
11306                     ActivityInfo ai = ri.activityInfo;
11307                     ApplicationInfo app = ai.applicationInfo;
11308                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11309                         mTopAction = Intent.ACTION_FACTORY_TEST;
11310                         mTopData = null;
11311                         mTopComponent = new ComponentName(app.packageName,
11312                                 ai.name);
11313                     } else {
11314                         errorMsg = mContext.getResources().getText(
11315                                 com.android.internal.R.string.factorytest_not_system);
11316                     }
11317                 } else {
11318                     errorMsg = mContext.getResources().getText(
11319                             com.android.internal.R.string.factorytest_no_action);
11320                 }
11321                 if (errorMsg != null) {
11322                     mTopAction = null;
11323                     mTopData = null;
11324                     mTopComponent = null;
11325                     Message msg = Message.obtain();
11326                     msg.what = SHOW_FACTORY_ERROR_MSG;
11327                     msg.getData().putCharSequence("msg", errorMsg);
11328                     mHandler.sendMessage(msg);
11329                 }
11330             }
11331         }
11332
11333         retrieveSettings();
11334         loadResourcesOnSystemReady();
11335
11336         synchronized (this) {
11337             readGrantedUriPermissionsLocked();
11338         }
11339
11340         if (goingCallback != null) goingCallback.run();
11341
11342         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11343                 Integer.toString(mCurrentUserId), mCurrentUserId);
11344         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11345                 Integer.toString(mCurrentUserId), mCurrentUserId);
11346         mSystemServiceManager.startUser(mCurrentUserId);
11347
11348         synchronized (this) {
11349             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11350                 try {
11351                     List apps = AppGlobals.getPackageManager().
11352                         getPersistentApplications(STOCK_PM_FLAGS);
11353                     if (apps != null) {
11354                         int N = apps.size();
11355                         int i;
11356                         for (i=0; i<N; i++) {
11357                             ApplicationInfo info
11358                                 = (ApplicationInfo)apps.get(i);
11359                             if (info != null &&
11360                                     !info.packageName.equals("android")) {
11361                                 addAppLocked(info, false, null /* ABI override */);
11362                             }
11363                         }
11364                     }
11365                 } catch (RemoteException ex) {
11366                     // pm is in same process, this will never happen.
11367                 }
11368             }
11369
11370             // Start up initial activity.
11371             mBooting = true;
11372             startHomeActivityLocked(mCurrentUserId);
11373
11374             try {
11375                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11376                     Message msg = Message.obtain();
11377                     msg.what = SHOW_UID_ERROR_MSG;
11378                     mHandler.sendMessage(msg);
11379                 }
11380             } catch (RemoteException e) {
11381             }
11382
11383             long ident = Binder.clearCallingIdentity();
11384             try {
11385                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11386                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11387                         | Intent.FLAG_RECEIVER_FOREGROUND);
11388                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11389                 broadcastIntentLocked(null, null, intent,
11390                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11391                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11392                 intent = new Intent(Intent.ACTION_USER_STARTING);
11393                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11394                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11395                 broadcastIntentLocked(null, null, intent,
11396                         null, new IIntentReceiver.Stub() {
11397                             @Override
11398                             public void performReceive(Intent intent, int resultCode, String data,
11399                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11400                                     throws RemoteException {
11401                             }
11402                         }, 0, null, null,
11403                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11404                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11405             } catch (Throwable t) {
11406                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11407             } finally {
11408                 Binder.restoreCallingIdentity(ident);
11409             }
11410             mStackSupervisor.resumeTopActivitiesLocked();
11411             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11412         }
11413     }
11414
11415     private boolean makeAppCrashingLocked(ProcessRecord app,
11416             String shortMsg, String longMsg, String stackTrace) {
11417         app.crashing = true;
11418         app.crashingReport = generateProcessError(app,
11419                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11420         startAppProblemLocked(app);
11421         app.stopFreezingAllLocked();
11422         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11423     }
11424
11425     private void makeAppNotRespondingLocked(ProcessRecord app,
11426             String activity, String shortMsg, String longMsg) {
11427         app.notResponding = true;
11428         app.notRespondingReport = generateProcessError(app,
11429                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11430                 activity, shortMsg, longMsg, null);
11431         startAppProblemLocked(app);
11432         app.stopFreezingAllLocked();
11433     }
11434     
11435     /**
11436      * Generate a process error record, suitable for attachment to a ProcessRecord.
11437      * 
11438      * @param app The ProcessRecord in which the error occurred.
11439      * @param condition Crashing, Application Not Responding, etc.  Values are defined in 
11440      *                      ActivityManager.AppErrorStateInfo
11441      * @param activity The activity associated with the crash, if known.
11442      * @param shortMsg Short message describing the crash.
11443      * @param longMsg Long message describing the crash.
11444      * @param stackTrace Full crash stack trace, may be null.
11445      *
11446      * @return Returns a fully-formed AppErrorStateInfo record.
11447      */
11448     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 
11449             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11450         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11451
11452         report.condition = condition;
11453         report.processName = app.processName;
11454         report.pid = app.pid;
11455         report.uid = app.info.uid;
11456         report.tag = activity;
11457         report.shortMsg = shortMsg;
11458         report.longMsg = longMsg;
11459         report.stackTrace = stackTrace;
11460
11461         return report;
11462     }
11463
11464     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11465         synchronized (this) {
11466             app.crashing = false;
11467             app.crashingReport = null;
11468             app.notResponding = false;
11469             app.notRespondingReport = null;
11470             if (app.anrDialog == fromDialog) {
11471                 app.anrDialog = null;
11472             }
11473             if (app.waitDialog == fromDialog) {
11474                 app.waitDialog = null;
11475             }
11476             if (app.pid > 0 && app.pid != MY_PID) {
11477                 handleAppCrashLocked(app, null, null, null);
11478                 app.kill("user request after error", true);
11479             }
11480         }
11481     }
11482
11483     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11484             String stackTrace) {
11485         long now = SystemClock.uptimeMillis();
11486
11487         Long crashTime;
11488         if (!app.isolated) {
11489             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11490         } else {
11491             crashTime = null;
11492         }
11493         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11494             // This process loses!
11495             Slog.w(TAG, "Process " + app.info.processName
11496                     + " has crashed too many times: killing!");
11497             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11498                     app.userId, app.info.processName, app.uid);
11499             mStackSupervisor.handleAppCrashLocked(app);
11500             if (!app.persistent) {
11501                 // We don't want to start this process again until the user
11502                 // explicitly does so...  but for persistent process, we really
11503                 // need to keep it running.  If a persistent process is actually
11504                 // repeatedly crashing, then badness for everyone.
11505                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11506                         app.info.processName);
11507                 if (!app.isolated) {
11508                     // XXX We don't have a way to mark isolated processes
11509                     // as bad, since they don't have a peristent identity.
11510                     mBadProcesses.put(app.info.processName, app.uid,
11511                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11512                     mProcessCrashTimes.remove(app.info.processName, app.uid);
11513                 }
11514                 app.bad = true;
11515                 app.removed = true;
11516                 // Don't let services in this process be restarted and potentially
11517                 // annoy the user repeatedly.  Unless it is persistent, since those
11518                 // processes run critical code.
11519                 removeProcessLocked(app, false, false, "crash");
11520                 mStackSupervisor.resumeTopActivitiesLocked();
11521                 return false;
11522             }
11523             mStackSupervisor.resumeTopActivitiesLocked();
11524         } else {
11525             mStackSupervisor.finishTopRunningActivityLocked(app);
11526         }
11527
11528         // Bump up the crash count of any services currently running in the proc.
11529         for (int i=app.services.size()-1; i>=0; i--) {
11530             // Any services running in the application need to be placed
11531             // back in the pending list.
11532             ServiceRecord sr = app.services.valueAt(i);
11533             sr.crashCount++;
11534         }
11535
11536         // If the crashing process is what we consider to be the "home process" and it has been
11537         // replaced by a third-party app, clear the package preferred activities from packages
11538         // with a home activity running in the process to prevent a repeatedly crashing app
11539         // from blocking the user to manually clear the list.
11540         final ArrayList<ActivityRecord> activities = app.activities;
11541         if (app == mHomeProcess && activities.size() > 0
11542                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11543             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11544                 final ActivityRecord r = activities.get(activityNdx);
11545                 if (r.isHomeActivity()) {
11546                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11547                     try {
11548                         ActivityThread.getPackageManager()
11549                                 .clearPackagePreferredActivities(r.packageName);
11550                     } catch (RemoteException c) {
11551                         // pm is in same process, this will never happen.
11552                     }
11553                 }
11554             }
11555         }
11556
11557         if (!app.isolated) {
11558             // XXX Can't keep track of crash times for isolated processes,
11559             // because they don't have a perisistent identity.
11560             mProcessCrashTimes.put(app.info.processName, app.uid, now);
11561         }
11562
11563         if (app.crashHandler != null) mHandler.post(app.crashHandler);
11564         return true;
11565     }
11566
11567     void startAppProblemLocked(ProcessRecord app) {
11568         // If this app is not running under the current user, then we
11569         // can't give it a report button because that would require
11570         // launching the report UI under a different user.
11571         app.errorReportReceiver = null;
11572
11573         for (int userId : mCurrentProfileIds) {
11574             if (app.userId == userId) {
11575                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11576                         mContext, app.info.packageName, app.info.flags);
11577             }
11578         }
11579         skipCurrentReceiverLocked(app);
11580     }
11581
11582     void skipCurrentReceiverLocked(ProcessRecord app) {
11583         for (BroadcastQueue queue : mBroadcastQueues) {
11584             queue.skipCurrentReceiverLocked(app);
11585         }
11586     }
11587
11588     /**
11589      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11590      * The application process will exit immediately after this call returns.
11591      * @param app object of the crashing app, null for the system server
11592      * @param crashInfo describing the exception
11593      */
11594     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11595         ProcessRecord r = findAppProcess(app, "Crash");
11596         final String processName = app == null ? "system_server"
11597                 : (r == null ? "unknown" : r.processName);
11598
11599         handleApplicationCrashInner("crash", r, processName, crashInfo);
11600     }
11601
11602     /* Native crash reporting uses this inner version because it needs to be somewhat
11603      * decoupled from the AM-managed cleanup lifecycle
11604      */
11605     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11606             ApplicationErrorReport.CrashInfo crashInfo) {
11607         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11608                 UserHandle.getUserId(Binder.getCallingUid()), processName,
11609                 r == null ? -1 : r.info.flags,
11610                 crashInfo.exceptionClassName,
11611                 crashInfo.exceptionMessage,
11612                 crashInfo.throwFileName,
11613                 crashInfo.throwLineNumber);
11614
11615         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11616
11617         crashApplication(r, crashInfo);
11618     }
11619
11620     public void handleApplicationStrictModeViolation(
11621             IBinder app,
11622             int violationMask,
11623             StrictMode.ViolationInfo info) {
11624         ProcessRecord r = findAppProcess(app, "StrictMode");
11625         if (r == null) {
11626             return;
11627         }
11628
11629         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11630             Integer stackFingerprint = info.hashCode();
11631             boolean logIt = true;
11632             synchronized (mAlreadyLoggedViolatedStacks) {
11633                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11634                     logIt = false;
11635                     // TODO: sub-sample into EventLog for these, with
11636                     // the info.durationMillis?  Then we'd get
11637                     // the relative pain numbers, without logging all
11638                     // the stack traces repeatedly.  We'd want to do
11639                     // likewise in the client code, which also does
11640                     // dup suppression, before the Binder call.
11641                 } else {
11642                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11643                         mAlreadyLoggedViolatedStacks.clear();
11644                     }
11645                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11646                 }
11647             }
11648             if (logIt) {
11649                 logStrictModeViolationToDropBox(r, info);
11650             }
11651         }
11652
11653         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11654             AppErrorResult result = new AppErrorResult();
11655             synchronized (this) {
11656                 final long origId = Binder.clearCallingIdentity();
11657
11658                 Message msg = Message.obtain();
11659                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11660                 HashMap<String, Object> data = new HashMap<String, Object>();
11661                 data.put("result", result);
11662                 data.put("app", r);
11663                 data.put("violationMask", violationMask);
11664                 data.put("info", info);
11665                 msg.obj = data;
11666                 mHandler.sendMessage(msg);
11667
11668                 Binder.restoreCallingIdentity(origId);
11669             }
11670             int res = result.get();
11671             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11672         }
11673     }
11674
11675     // Depending on the policy in effect, there could be a bunch of
11676     // these in quick succession so we try to batch these together to
11677     // minimize disk writes, number of dropbox entries, and maximize
11678     // compression, by having more fewer, larger records.
11679     private void logStrictModeViolationToDropBox(
11680             ProcessRecord process,
11681             StrictMode.ViolationInfo info) {
11682         if (info == null) {
11683             return;
11684         }
11685         final boolean isSystemApp = process == null ||
11686                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11687                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11688         final String processName = process == null ? "unknown" : process.processName;
11689         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11690         final DropBoxManager dbox = (DropBoxManager)
11691                 mContext.getSystemService(Context.DROPBOX_SERVICE);
11692
11693         // Exit early if the dropbox isn't configured to accept this report type.
11694         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11695
11696         boolean bufferWasEmpty;
11697         boolean needsFlush;
11698         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11699         synchronized (sb) {
11700             bufferWasEmpty = sb.length() == 0;
11701             appendDropBoxProcessHeaders(process, processName, sb);
11702             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11703             sb.append("System-App: ").append(isSystemApp).append("\n");
11704             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11705             if (info.violationNumThisLoop != 0) {
11706                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11707             }
11708             if (info.numAnimationsRunning != 0) {
11709                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11710             }
11711             if (info.broadcastIntentAction != null) {
11712                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11713             }
11714             if (info.durationMillis != -1) {
11715                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11716             }
11717             if (info.numInstances != -1) {
11718                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11719             }
11720             if (info.tags != null) {
11721                 for (String tag : info.tags) {
11722                     sb.append("Span-Tag: ").append(tag).append("\n");
11723                 }
11724             }
11725             sb.append("\n");
11726             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11727                 sb.append(info.crashInfo.stackTrace);
11728             }
11729             sb.append("\n");
11730
11731             // Only buffer up to ~64k.  Various logging bits truncate
11732             // things at 128k.
11733             needsFlush = (sb.length() > 64 * 1024);
11734         }
11735
11736         // Flush immediately if the buffer's grown too large, or this
11737         // is a non-system app.  Non-system apps are isolated with a
11738         // different tag & policy and not batched.
11739         //
11740         // Batching is useful during internal testing with
11741         // StrictMode settings turned up high.  Without batching,
11742         // thousands of separate files could be created on boot.
11743         if (!isSystemApp || needsFlush) {
11744             new Thread("Error dump: " + dropboxTag) {
11745                 @Override
11746                 public void run() {
11747                     String report;
11748                     synchronized (sb) {
11749                         report = sb.toString();
11750                         sb.delete(0, sb.length());
11751                         sb.trimToSize();
11752                     }
11753                     if (report.length() != 0) {
11754                         dbox.addText(dropboxTag, report);
11755                     }
11756                 }
11757             }.start();
11758             return;
11759         }
11760
11761         // System app batching:
11762         if (!bufferWasEmpty) {
11763             // An existing dropbox-writing thread is outstanding, so
11764             // we don't need to start it up.  The existing thread will
11765             // catch the buffer appends we just did.
11766             return;
11767         }
11768
11769         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11770         // (After this point, we shouldn't access AMS internal data structures.)
11771         new Thread("Error dump: " + dropboxTag) {
11772             @Override
11773             public void run() {
11774                 // 5 second sleep to let stacks arrive and be batched together
11775                 try {
11776                     Thread.sleep(5000);  // 5 seconds
11777                 } catch (InterruptedException e) {}
11778
11779                 String errorReport;
11780                 synchronized (mStrictModeBuffer) {
11781                     errorReport = mStrictModeBuffer.toString();
11782                     if (errorReport.length() == 0) {
11783                         return;
11784                     }
11785                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11786                     mStrictModeBuffer.trimToSize();
11787                 }
11788                 dbox.addText(dropboxTag, errorReport);
11789             }
11790         }.start();
11791     }
11792
11793     /**
11794      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11795      * @param app object of the crashing app, null for the system server
11796      * @param tag reported by the caller
11797      * @param system whether this wtf is coming from the system
11798      * @param crashInfo describing the context of the error
11799      * @return true if the process should exit immediately (WTF is fatal)
11800      */
11801     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11802             final ApplicationErrorReport.CrashInfo crashInfo) {
11803         final int callingUid = Binder.getCallingUid();
11804         final int callingPid = Binder.getCallingPid();
11805
11806         if (system) {
11807             // If this is coming from the system, we could very well have low-level
11808             // system locks held, so we want to do this all asynchronously.  And we
11809             // never want this to become fatal, so there is that too.
11810             mHandler.post(new Runnable() {
11811                 @Override public void run() {
11812                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11813                 }
11814             });
11815             return false;
11816         }
11817
11818         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11819                 crashInfo);
11820
11821         if (r != null && r.pid != Process.myPid() &&
11822                 Settings.Global.getInt(mContext.getContentResolver(),
11823                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
11824             crashApplication(r, crashInfo);
11825             return true;
11826         } else {
11827             return false;
11828         }
11829     }
11830
11831     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11832             final ApplicationErrorReport.CrashInfo crashInfo) {
11833         final ProcessRecord r = findAppProcess(app, "WTF");
11834         final String processName = app == null ? "system_server"
11835                 : (r == null ? "unknown" : r.processName);
11836
11837         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11838                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11839
11840         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11841
11842         return r;
11843     }
11844
11845     /**
11846      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11847      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11848      */
11849     private ProcessRecord findAppProcess(IBinder app, String reason) {
11850         if (app == null) {
11851             return null;
11852         }
11853
11854         synchronized (this) {
11855             final int NP = mProcessNames.getMap().size();
11856             for (int ip=0; ip<NP; ip++) {
11857                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11858                 final int NA = apps.size();
11859                 for (int ia=0; ia<NA; ia++) {
11860                     ProcessRecord p = apps.valueAt(ia);
11861                     if (p.thread != null && p.thread.asBinder() == app) {
11862                         return p;
11863                     }
11864                 }
11865             }
11866
11867             Slog.w(TAG, "Can't find mystery application for " + reason
11868                     + " from pid=" + Binder.getCallingPid()
11869                     + " uid=" + Binder.getCallingUid() + ": " + app);
11870             return null;
11871         }
11872     }
11873
11874     /**
11875      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11876      * to append various headers to the dropbox log text.
11877      */
11878     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11879             StringBuilder sb) {
11880         // Watchdog thread ends up invoking this function (with
11881         // a null ProcessRecord) to add the stack file to dropbox.
11882         // Do not acquire a lock on this (am) in such cases, as it
11883         // could cause a potential deadlock, if and when watchdog
11884         // is invoked due to unavailability of lock on am and it
11885         // would prevent watchdog from killing system_server.
11886         if (process == null) {
11887             sb.append("Process: ").append(processName).append("\n");
11888             return;
11889         }
11890         // Note: ProcessRecord 'process' is guarded by the service
11891         // instance.  (notably process.pkgList, which could otherwise change
11892         // concurrently during execution of this method)
11893         synchronized (this) {
11894             sb.append("Process: ").append(processName).append("\n");
11895             int flags = process.info.flags;
11896             IPackageManager pm = AppGlobals.getPackageManager();
11897             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11898             for (int ip=0; ip<process.pkgList.size(); ip++) {
11899                 String pkg = process.pkgList.keyAt(ip);
11900                 sb.append("Package: ").append(pkg);
11901                 try {
11902                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11903                     if (pi != null) {
11904                         sb.append(" v").append(pi.versionCode);
11905                         if (pi.versionName != null) {
11906                             sb.append(" (").append(pi.versionName).append(")");
11907                         }
11908                     }
11909                 } catch (RemoteException e) {
11910                     Slog.e(TAG, "Error getting package info: " + pkg, e);
11911                 }
11912                 sb.append("\n");
11913             }
11914         }
11915     }
11916
11917     private static String processClass(ProcessRecord process) {
11918         if (process == null || process.pid == MY_PID) {
11919             return "system_server";
11920         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11921             return "system_app";
11922         } else {
11923             return "data_app";
11924         }
11925     }
11926
11927     /**
11928      * Write a description of an error (crash, WTF, ANR) to the drop box.
11929      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11930      * @param process which caused the error, null means the system server
11931      * @param activity which triggered the error, null if unknown
11932      * @param parent activity related to the error, null if unknown
11933      * @param subject line related to the error, null if absent
11934      * @param report in long form describing the error, null if absent
11935      * @param logFile to include in the report, null if none
11936      * @param crashInfo giving an application stack trace, null if absent
11937      */
11938     public void addErrorToDropBox(String eventType,
11939             ProcessRecord process, String processName, ActivityRecord activity,
11940             ActivityRecord parent, String subject,
11941             final String report, final File logFile,
11942             final ApplicationErrorReport.CrashInfo crashInfo) {
11943         // NOTE -- this must never acquire the ActivityManagerService lock,
11944         // otherwise the watchdog may be prevented from resetting the system.
11945
11946         final String dropboxTag = processClass(process) + "_" + eventType;
11947         final DropBoxManager dbox = (DropBoxManager)
11948                 mContext.getSystemService(Context.DROPBOX_SERVICE);
11949
11950         // Exit early if the dropbox isn't configured to accept this report type.
11951         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11952
11953         final StringBuilder sb = new StringBuilder(1024);
11954         appendDropBoxProcessHeaders(process, processName, sb);
11955         if (activity != null) {
11956             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11957         }
11958         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11959             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11960         }
11961         if (parent != null && parent != activity) {
11962             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11963         }
11964         if (subject != null) {
11965             sb.append("Subject: ").append(subject).append("\n");
11966         }
11967         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11968         if (Debug.isDebuggerConnected()) {
11969             sb.append("Debugger: Connected\n");
11970         }
11971         sb.append("\n");
11972
11973         // Do the rest in a worker thread to avoid blocking the caller on I/O
11974         // (After this point, we shouldn't access AMS internal data structures.)
11975         Thread worker = new Thread("Error dump: " + dropboxTag) {
11976             @Override
11977             public void run() {
11978                 if (report != null) {
11979                     sb.append(report);
11980                 }
11981                 if (logFile != null) {
11982                     try {
11983                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11984                                     "\n\n[[TRUNCATED]]"));
11985                     } catch (IOException e) {
11986                         Slog.e(TAG, "Error reading " + logFile, e);
11987                     }
11988                 }
11989                 if (crashInfo != null && crashInfo.stackTrace != null) {
11990                     sb.append(crashInfo.stackTrace);
11991                 }
11992
11993                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11994                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11995                 if (lines > 0) {
11996                     sb.append("\n");
11997
11998                     // Merge several logcat streams, and take the last N lines
11999                     InputStreamReader input = null;
12000                     try {
12001                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12002                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12003                                 "-b", "crash",
12004                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12005
12006                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12007                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12008                         input = new InputStreamReader(logcat.getInputStream());
12009
12010                         int num;
12011                         char[] buf = new char[8192];
12012                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12013                     } catch (IOException e) {
12014                         Slog.e(TAG, "Error running logcat", e);
12015                     } finally {
12016                         if (input != null) try { input.close(); } catch (IOException e) {}
12017                     }
12018                 }
12019
12020                 dbox.addText(dropboxTag, sb.toString());
12021             }
12022         };
12023
12024         if (process == null) {
12025             // If process is null, we are being called from some internal code
12026             // and may be about to die -- run this synchronously.
12027             worker.run();
12028         } else {
12029             worker.start();
12030         }
12031     }
12032
12033     /**
12034      * Bring up the "unexpected error" dialog box for a crashing app.
12035      * Deal with edge cases (intercepts from instrumented applications,
12036      * ActivityController, error intent receivers, that sort of thing).
12037      * @param r the application crashing
12038      * @param crashInfo describing the failure
12039      */
12040     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12041         long timeMillis = System.currentTimeMillis();
12042         String shortMsg = crashInfo.exceptionClassName;
12043         String longMsg = crashInfo.exceptionMessage;
12044         String stackTrace = crashInfo.stackTrace;
12045         if (shortMsg != null && longMsg != null) {
12046             longMsg = shortMsg + ": " + longMsg;
12047         } else if (shortMsg != null) {
12048             longMsg = shortMsg;
12049         }
12050
12051         AppErrorResult result = new AppErrorResult();
12052         synchronized (this) {
12053             if (mController != null) {
12054                 try {
12055                     String name = r != null ? r.processName : null;
12056                     int pid = r != null ? r.pid : Binder.getCallingPid();
12057                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12058                     if (!mController.appCrashed(name, pid,
12059                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12060                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12061                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12062                             Slog.w(TAG, "Skip killing native crashed app " + name
12063                                     + "(" + pid + ") during testing");
12064                         } else {
12065                             Slog.w(TAG, "Force-killing crashed app " + name
12066                                     + " at watcher's request");
12067                             if (r != null) {
12068                                 r.kill("crash", true);
12069                             } else {
12070                                 // Huh.
12071                                 Process.killProcess(pid);
12072                                 Process.killProcessGroup(uid, pid);
12073                             }
12074                         }
12075                         return;
12076                     }
12077                 } catch (RemoteException e) {
12078                     mController = null;
12079                     Watchdog.getInstance().setActivityController(null);
12080                 }
12081             }
12082
12083             final long origId = Binder.clearCallingIdentity();
12084
12085             // If this process is running instrumentation, finish it.
12086             if (r != null && r.instrumentationClass != null) {
12087                 Slog.w(TAG, "Error in app " + r.processName
12088                       + " running instrumentation " + r.instrumentationClass + ":");
12089                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12090                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12091                 Bundle info = new Bundle();
12092                 info.putString("shortMsg", shortMsg);
12093                 info.putString("longMsg", longMsg);
12094                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12095                 Binder.restoreCallingIdentity(origId);
12096                 return;
12097             }
12098
12099             // If we can't identify the process or it's already exceeded its crash quota,
12100             // quit right away without showing a crash dialog.
12101             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12102                 Binder.restoreCallingIdentity(origId);
12103                 return;
12104             }
12105
12106             Message msg = Message.obtain();
12107             msg.what = SHOW_ERROR_MSG;
12108             HashMap data = new HashMap();
12109             data.put("result", result);
12110             data.put("app", r);
12111             msg.obj = data;
12112             mHandler.sendMessage(msg);
12113
12114             Binder.restoreCallingIdentity(origId);
12115         }
12116
12117         int res = result.get();
12118
12119         Intent appErrorIntent = null;
12120         synchronized (this) {
12121             if (r != null && !r.isolated) {
12122                 // XXX Can't keep track of crash time for isolated processes,
12123                 // since they don't have a persistent identity.
12124                 mProcessCrashTimes.put(r.info.processName, r.uid,
12125                         SystemClock.uptimeMillis());
12126             }
12127             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12128                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12129             }
12130         }
12131
12132         if (appErrorIntent != null) {
12133             try {
12134                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12135             } catch (ActivityNotFoundException e) {
12136                 Slog.w(TAG, "bug report receiver dissappeared", e);
12137             }
12138         }
12139     }
12140
12141     Intent createAppErrorIntentLocked(ProcessRecord r,
12142             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12143         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12144         if (report == null) {
12145             return null;
12146         }
12147         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12148         result.setComponent(r.errorReportReceiver);
12149         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12150         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12151         return result;
12152     }
12153
12154     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12155             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12156         if (r.errorReportReceiver == null) {
12157             return null;
12158         }
12159
12160         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12161             return null;
12162         }
12163
12164         ApplicationErrorReport report = new ApplicationErrorReport();
12165         report.packageName = r.info.packageName;
12166         report.installerPackageName = r.errorReportReceiver.getPackageName();
12167         report.processName = r.processName;
12168         report.time = timeMillis;
12169         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12170
12171         if (r.crashing || r.forceCrashReport) {
12172             report.type = ApplicationErrorReport.TYPE_CRASH;
12173             report.crashInfo = crashInfo;
12174         } else if (r.notResponding) {
12175             report.type = ApplicationErrorReport.TYPE_ANR;
12176             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12177
12178             report.anrInfo.activity = r.notRespondingReport.tag;
12179             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12180             report.anrInfo.info = r.notRespondingReport.longMsg;
12181         }
12182
12183         return report;
12184     }
12185
12186     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12187         enforceNotIsolatedCaller("getProcessesInErrorState");
12188         // assume our apps are happy - lazy create the list
12189         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12190
12191         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12192                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12193         int userId = UserHandle.getUserId(Binder.getCallingUid());
12194
12195         synchronized (this) {
12196
12197             // iterate across all processes
12198             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12199                 ProcessRecord app = mLruProcesses.get(i);
12200                 if (!allUsers && app.userId != userId) {
12201                     continue;
12202                 }
12203                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12204                     // This one's in trouble, so we'll generate a report for it
12205                     // crashes are higher priority (in case there's a crash *and* an anr)
12206                     ActivityManager.ProcessErrorStateInfo report = null;
12207                     if (app.crashing) {
12208                         report = app.crashingReport;
12209                     } else if (app.notResponding) {
12210                         report = app.notRespondingReport;
12211                     }
12212                     
12213                     if (report != null) {
12214                         if (errList == null) {
12215                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12216                         }
12217                         errList.add(report);
12218                     } else {
12219                         Slog.w(TAG, "Missing app error report, app = " + app.processName + 
12220                                 " crashing = " + app.crashing +
12221                                 " notResponding = " + app.notResponding);
12222                     }
12223                 }
12224             }
12225         }
12226
12227         return errList;
12228     }
12229
12230     static int procStateToImportance(int procState, int memAdj,
12231             ActivityManager.RunningAppProcessInfo currApp) {
12232         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12233         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12234             currApp.lru = memAdj;
12235         } else {
12236             currApp.lru = 0;
12237         }
12238         return imp;
12239     }
12240
12241     private void fillInProcMemInfo(ProcessRecord app,
12242             ActivityManager.RunningAppProcessInfo outInfo) {
12243         outInfo.pid = app.pid;
12244         outInfo.uid = app.info.uid;
12245         if (mHeavyWeightProcess == app) {
12246             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12247         }
12248         if (app.persistent) {
12249             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12250         }
12251         if (app.activities.size() > 0) {
12252             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12253         }
12254         outInfo.lastTrimLevel = app.trimMemoryLevel;
12255         int adj = app.curAdj;
12256         int procState = app.curProcState;
12257         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12258         outInfo.importanceReasonCode = app.adjTypeCode;
12259         outInfo.processState = app.curProcState;
12260     }
12261
12262     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12263         enforceNotIsolatedCaller("getRunningAppProcesses");
12264
12265         final int callingUid = Binder.getCallingUid();
12266
12267         // Lazy instantiation of list
12268         List<ActivityManager.RunningAppProcessInfo> runList = null;
12269         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12270                 callingUid) == PackageManager.PERMISSION_GRANTED;
12271         final int userId = UserHandle.getUserId(callingUid);
12272         final boolean allUids = isGetTasksAllowed(
12273                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12274
12275         synchronized (this) {
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                         || (!allUids && app.uid != callingUid)) {
12281                     continue;
12282                 }
12283                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12284                     // Generate process state info for running application
12285                     ActivityManager.RunningAppProcessInfo currApp = 
12286                         new ActivityManager.RunningAppProcessInfo(app.processName,
12287                                 app.pid, app.getPackageList());
12288                     fillInProcMemInfo(app, currApp);
12289                     if (app.adjSource instanceof ProcessRecord) {
12290                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12291                         currApp.importanceReasonImportance =
12292                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12293                                         app.adjSourceProcState);
12294                     } else if (app.adjSource instanceof ActivityRecord) {
12295                         ActivityRecord r = (ActivityRecord)app.adjSource;
12296                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12297                     }
12298                     if (app.adjTarget instanceof ComponentName) {
12299                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12300                     }
12301                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12302                     //        + " lru=" + currApp.lru);
12303                     if (runList == null) {
12304                         runList = new ArrayList<>();
12305                     }
12306                     runList.add(currApp);
12307                 }
12308             }
12309         }
12310         return runList;
12311     }
12312
12313     public List<ApplicationInfo> getRunningExternalApplications() {
12314         enforceNotIsolatedCaller("getRunningExternalApplications");
12315         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12316         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12317         if (runningApps != null && runningApps.size() > 0) {
12318             Set<String> extList = new HashSet<String>();
12319             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12320                 if (app.pkgList != null) {
12321                     for (String pkg : app.pkgList) {
12322                         extList.add(pkg);
12323                     }
12324                 }
12325             }
12326             IPackageManager pm = AppGlobals.getPackageManager();
12327             for (String pkg : extList) {
12328                 try {
12329                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12330                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12331                         retList.add(info);
12332                     }
12333                 } catch (RemoteException e) {
12334                 }
12335             }
12336         }
12337         return retList;
12338     }
12339
12340     @Override
12341     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12342         enforceNotIsolatedCaller("getMyMemoryState");
12343         synchronized (this) {
12344             ProcessRecord proc;
12345             synchronized (mPidsSelfLocked) {
12346                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12347             }
12348             fillInProcMemInfo(proc, outInfo);
12349         }
12350     }
12351
12352     @Override
12353     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12354         if (checkCallingPermission(android.Manifest.permission.DUMP)
12355                 != PackageManager.PERMISSION_GRANTED) {
12356             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12357                     + Binder.getCallingPid()
12358                     + ", uid=" + Binder.getCallingUid()
12359                     + " without permission "
12360                     + android.Manifest.permission.DUMP);
12361             return;
12362         }
12363
12364         boolean dumpAll = false;
12365         boolean dumpClient = false;
12366         String dumpPackage = null;
12367         
12368         int opti = 0;
12369         while (opti < args.length) {
12370             String opt = args[opti];
12371             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12372                 break;
12373             }
12374             opti++;
12375             if ("-a".equals(opt)) {
12376                 dumpAll = true;
12377             } else if ("-c".equals(opt)) {
12378                 dumpClient = true;
12379             } else if ("-h".equals(opt)) {
12380                 pw.println("Activity manager dump options:");
12381                 pw.println("  [-a] [-c] [-h] [cmd] ...");
12382                 pw.println("  cmd may be one of:");
12383                 pw.println("    a[ctivities]: activity stack state");
12384                 pw.println("    r[recents]: recent activities state");
12385                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12386                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12387                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12388                 pw.println("    o[om]: out of memory management");
12389                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12390                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12391                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12392                 pw.println("    service [COMP_SPEC]: service client-side state");
12393                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12394                 pw.println("    all: dump all activities");
12395                 pw.println("    top: dump the top activity");
12396                 pw.println("    write: write all pending state to storage");
12397                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12398                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12399                 pw.println("    a partial substring in a component name, a");
12400                 pw.println("    hex object identifier.");
12401                 pw.println("  -a: include all available server state.");
12402                 pw.println("  -c: include client state.");
12403                 return;
12404             } else {
12405                 pw.println("Unknown argument: " + opt + "; use -h for help");
12406             }
12407         }
12408
12409         long origId = Binder.clearCallingIdentity();
12410         boolean more = false;
12411         // Is the caller requesting to dump a particular piece of data?
12412         if (opti < args.length) {
12413             String cmd = args[opti];
12414             opti++;
12415             if ("activities".equals(cmd) || "a".equals(cmd)) {
12416                 synchronized (this) {
12417                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12418                 }
12419             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12420                 synchronized (this) {
12421                     dumpRecentsLocked(fd, pw, args, opti, true, null);
12422                 }
12423             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12424                 String[] newArgs;
12425                 String name;
12426                 if (opti >= args.length) {
12427                     name = null;
12428                     newArgs = EMPTY_STRING_ARRAY;
12429                 } else {
12430                     name = args[opti];
12431                     opti++;
12432                     newArgs = new String[args.length - opti];
12433                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12434                             args.length - opti);
12435                 }
12436                 synchronized (this) {
12437                     dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12438                 }
12439             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12440                 String[] newArgs;
12441                 String name;
12442                 if (opti >= args.length) {
12443                     name = null;
12444                     newArgs = EMPTY_STRING_ARRAY;
12445                 } else {
12446                     name = args[opti];
12447                     opti++;
12448                     newArgs = new String[args.length - opti];
12449                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12450                             args.length - opti);
12451                 }
12452                 synchronized (this) {
12453                     dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12454                 }
12455             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12456                 String[] newArgs;
12457                 String name;
12458                 if (opti >= args.length) {
12459                     name = null;
12460                     newArgs = EMPTY_STRING_ARRAY;
12461                 } else {
12462                     name = args[opti];
12463                     opti++;
12464                     newArgs = new String[args.length - opti];
12465                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12466                             args.length - opti);
12467                 }
12468                 synchronized (this) {
12469                     dumpProcessesLocked(fd, pw, args, opti, true, name);
12470                 }
12471             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12472                 synchronized (this) {
12473                     dumpOomLocked(fd, pw, args, opti, true);
12474                 }
12475             } else if ("provider".equals(cmd)) {
12476                 String[] newArgs;
12477                 String name;
12478                 if (opti >= args.length) {
12479                     name = null;
12480                     newArgs = EMPTY_STRING_ARRAY;
12481                 } else {
12482                     name = args[opti];
12483                     opti++;
12484                     newArgs = new String[args.length - opti];
12485                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12486                 }
12487                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12488                     pw.println("No providers match: " + name);
12489                     pw.println("Use -h for help.");
12490                 }
12491             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12492                 synchronized (this) {
12493                     dumpProvidersLocked(fd, pw, args, opti, true, null);
12494                 }
12495             } else if ("service".equals(cmd)) {
12496                 String[] newArgs;
12497                 String name;
12498                 if (opti >= args.length) {
12499                     name = null;
12500                     newArgs = EMPTY_STRING_ARRAY;
12501                 } else {
12502                     name = args[opti];
12503                     opti++;
12504                     newArgs = new String[args.length - opti];
12505                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12506                             args.length - opti);
12507                 }
12508                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12509                     pw.println("No services match: " + name);
12510                     pw.println("Use -h for help.");
12511                 }
12512             } else if ("package".equals(cmd)) {
12513                 String[] newArgs;
12514                 if (opti >= args.length) {
12515                     pw.println("package: no package name specified");
12516                     pw.println("Use -h for help.");
12517                 } else {
12518                     dumpPackage = args[opti];
12519                     opti++;
12520                     newArgs = new String[args.length - opti];
12521                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12522                             args.length - opti);
12523                     args = newArgs;
12524                     opti = 0;
12525                     more = true;
12526                 }
12527             } else if ("services".equals(cmd) || "s".equals(cmd)) {
12528                 synchronized (this) {
12529                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12530                 }
12531             } else if ("write".equals(cmd)) {
12532                 mTaskPersister.flush();
12533                 pw.println("All tasks persisted.");
12534                 return;
12535             } else {
12536                 // Dumping a single activity?
12537                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12538                     pw.println("Bad activity command, or no activities match: " + cmd);
12539                     pw.println("Use -h for help.");
12540                 }
12541             }
12542             if (!more) {
12543                 Binder.restoreCallingIdentity(origId);
12544                 return;
12545             }
12546         }
12547
12548         // No piece of data specified, dump everything.
12549         synchronized (this) {
12550             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12551             pw.println();
12552             if (dumpAll) {
12553                 pw.println("-------------------------------------------------------------------------------");
12554             }
12555             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12556             pw.println();
12557             if (dumpAll) {
12558                 pw.println("-------------------------------------------------------------------------------");
12559             }
12560             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12561             pw.println();
12562             if (dumpAll) {
12563                 pw.println("-------------------------------------------------------------------------------");
12564             }
12565             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12566             pw.println();
12567             if (dumpAll) {
12568                 pw.println("-------------------------------------------------------------------------------");
12569             }
12570             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12571             pw.println();
12572             if (dumpAll) {
12573                 pw.println("-------------------------------------------------------------------------------");
12574             }
12575             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12576             pw.println();
12577             if (dumpAll) {
12578                 pw.println("-------------------------------------------------------------------------------");
12579             }
12580             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12581         }
12582         Binder.restoreCallingIdentity(origId);
12583     }
12584
12585     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12586             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12587         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12588
12589         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12590                 dumpPackage);
12591         boolean needSep = printedAnything;
12592
12593         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12594                 dumpPackage, needSep, "  mFocusedActivity: ");
12595         if (printed) {
12596             printedAnything = true;
12597             needSep = false;
12598         }
12599
12600         if (dumpPackage == null) {
12601             if (needSep) {
12602                 pw.println();
12603             }
12604             needSep = true;
12605             printedAnything = true;
12606             mStackSupervisor.dump(pw, "  ");
12607         }
12608
12609         if (!printedAnything) {
12610             pw.println("  (nothing)");
12611         }
12612     }
12613
12614     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12615             int opti, boolean dumpAll, String dumpPackage) {
12616         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12617
12618         boolean printedAnything = false;
12619
12620         if (mRecentTasks != null && mRecentTasks.size() > 0) {
12621             boolean printedHeader = false;
12622
12623             final int N = mRecentTasks.size();
12624             for (int i=0; i<N; i++) {
12625                 TaskRecord tr = mRecentTasks.get(i);
12626                 if (dumpPackage != null) {
12627                     if (tr.realActivity == null ||
12628                             !dumpPackage.equals(tr.realActivity)) {
12629                         continue;
12630                     }
12631                 }
12632                 if (!printedHeader) {
12633                     pw.println("  Recent tasks:");
12634                     printedHeader = true;
12635                     printedAnything = true;
12636                 }
12637                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12638                         pw.println(tr);
12639                 if (dumpAll) {
12640                     mRecentTasks.get(i).dump(pw, "    ");
12641                 }
12642             }
12643         }
12644
12645         if (!printedAnything) {
12646             pw.println("  (nothing)");
12647         }
12648     }
12649
12650     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12651             int opti, boolean dumpAll, String dumpPackage) {
12652         boolean needSep = false;
12653         boolean printedAnything = false;
12654         int numPers = 0;
12655
12656         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12657
12658         if (dumpAll) {
12659             final int NP = mProcessNames.getMap().size();
12660             for (int ip=0; ip<NP; ip++) {
12661                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12662                 final int NA = procs.size();
12663                 for (int ia=0; ia<NA; ia++) {
12664                     ProcessRecord r = procs.valueAt(ia);
12665                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12666                         continue;
12667                     }
12668                     if (!needSep) {
12669                         pw.println("  All known processes:");
12670                         needSep = true;
12671                         printedAnything = true;
12672                     }
12673                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12674                         pw.print(" UID "); pw.print(procs.keyAt(ia));
12675                         pw.print(" "); pw.println(r);
12676                     r.dump(pw, "    ");
12677                     if (r.persistent) {
12678                         numPers++;
12679                     }
12680                 }
12681             }
12682         }
12683
12684         if (mIsolatedProcesses.size() > 0) {
12685             boolean printed = false;
12686             for (int i=0; i<mIsolatedProcesses.size(); i++) {
12687                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12688                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12689                     continue;
12690                 }
12691                 if (!printed) {
12692                     if (needSep) {
12693                         pw.println();
12694                     }
12695                     pw.println("  Isolated process list (sorted by uid):");
12696                     printedAnything = true;
12697                     printed = true;
12698                     needSep = true;
12699                 }
12700                 pw.println(String.format("%sIsolated #%2d: %s",
12701                         "    ", i, r.toString()));
12702             }
12703         }
12704
12705         if (mLruProcesses.size() > 0) {
12706             if (needSep) {
12707                 pw.println();
12708             }
12709             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12710                     pw.print(" total, non-act at ");
12711                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12712                     pw.print(", non-svc at ");
12713                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12714                     pw.println("):");
12715             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12716             needSep = true;
12717             printedAnything = true;
12718         }
12719
12720         if (dumpAll || dumpPackage != null) {
12721             synchronized (mPidsSelfLocked) {
12722                 boolean printed = false;
12723                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12724                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
12725                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12726                         continue;
12727                     }
12728                     if (!printed) {
12729                         if (needSep) pw.println();
12730                         needSep = true;
12731                         pw.println("  PID mappings:");
12732                         printed = true;
12733                         printedAnything = true;
12734                     }
12735                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12736                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12737                 }
12738             }
12739         }
12740         
12741         if (mForegroundProcesses.size() > 0) {
12742             synchronized (mPidsSelfLocked) {
12743                 boolean printed = false;
12744                 for (int i=0; i<mForegroundProcesses.size(); i++) {
12745                     ProcessRecord r = mPidsSelfLocked.get( 
12746                             mForegroundProcesses.valueAt(i).pid);
12747                     if (dumpPackage != null && (r == null
12748                             || !r.pkgList.containsKey(dumpPackage))) {
12749                         continue;
12750                     }
12751                     if (!printed) {
12752                         if (needSep) pw.println();
12753                         needSep = true;
12754                         pw.println("  Foreground Processes:");
12755                         printed = true;
12756                         printedAnything = true;
12757                     }
12758                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12759                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12760                 }
12761             }
12762         }
12763         
12764         if (mPersistentStartingProcesses.size() > 0) {
12765             if (needSep) pw.println();
12766             needSep = true;
12767             printedAnything = true;
12768             pw.println("  Persisent processes that are starting:");
12769             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12770                     "Starting Norm", "Restarting PERS", dumpPackage);
12771         }
12772
12773         if (mRemovedProcesses.size() > 0) {
12774             if (needSep) pw.println();
12775             needSep = true;
12776             printedAnything = true;
12777             pw.println("  Processes that are being removed:");
12778             dumpProcessList(pw, this, mRemovedProcesses, "    ",
12779                     "Removed Norm", "Removed PERS", dumpPackage);
12780         }
12781         
12782         if (mProcessesOnHold.size() > 0) {
12783             if (needSep) pw.println();
12784             needSep = true;
12785             printedAnything = true;
12786             pw.println("  Processes that are on old until the system is ready:");
12787             dumpProcessList(pw, this, mProcessesOnHold, "    ",
12788                     "OnHold Norm", "OnHold PERS", dumpPackage);
12789         }
12790
12791         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12792         
12793         if (mProcessCrashTimes.getMap().size() > 0) {
12794             boolean printed = false;
12795             long now = SystemClock.uptimeMillis();
12796             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12797             final int NP = pmap.size();
12798             for (int ip=0; ip<NP; ip++) {
12799                 String pname = pmap.keyAt(ip);
12800                 SparseArray<Long> uids = pmap.valueAt(ip);
12801                 final int N = uids.size();
12802                 for (int i=0; i<N; i++) {
12803                     int puid = uids.keyAt(i);
12804                     ProcessRecord r = mProcessNames.get(pname, puid);
12805                     if (dumpPackage != null && (r == null
12806                             || !r.pkgList.containsKey(dumpPackage))) {
12807                         continue;
12808                     }
12809                     if (!printed) {
12810                         if (needSep) pw.println();
12811                         needSep = true;
12812                         pw.println("  Time since processes crashed:");
12813                         printed = true;
12814                         printedAnything = true;
12815                     }
12816                     pw.print("    Process "); pw.print(pname);
12817                             pw.print(" uid "); pw.print(puid);
12818                             pw.print(": last crashed ");
12819                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12820                             pw.println(" ago");
12821                 }
12822             }
12823         }
12824
12825         if (mBadProcesses.getMap().size() > 0) {
12826             boolean printed = false;
12827             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12828             final int NP = pmap.size();
12829             for (int ip=0; ip<NP; ip++) {
12830                 String pname = pmap.keyAt(ip);
12831                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12832                 final int N = uids.size();
12833                 for (int i=0; i<N; i++) {
12834                     int puid = uids.keyAt(i);
12835                     ProcessRecord r = mProcessNames.get(pname, puid);
12836                     if (dumpPackage != null && (r == null
12837                             || !r.pkgList.containsKey(dumpPackage))) {
12838                         continue;
12839                     }
12840                     if (!printed) {
12841                         if (needSep) pw.println();
12842                         needSep = true;
12843                         pw.println("  Bad processes:");
12844                         printedAnything = true;
12845                     }
12846                     BadProcessInfo info = uids.valueAt(i);
12847                     pw.print("    Bad process "); pw.print(pname);
12848                             pw.print(" uid "); pw.print(puid);
12849                             pw.print(": crashed at time "); pw.println(info.time);
12850                     if (info.shortMsg != null) {
12851                         pw.print("      Short msg: "); pw.println(info.shortMsg);
12852                     }
12853                     if (info.longMsg != null) {
12854                         pw.print("      Long msg: "); pw.println(info.longMsg);
12855                     }
12856                     if (info.stack != null) {
12857                         pw.println("      Stack:");
12858                         int lastPos = 0;
12859                         for (int pos=0; pos<info.stack.length(); pos++) {
12860                             if (info.stack.charAt(pos) == '\n') {
12861                                 pw.print("        ");
12862                                 pw.write(info.stack, lastPos, pos-lastPos);
12863                                 pw.println();
12864                                 lastPos = pos+1;
12865                             }
12866                         }
12867                         if (lastPos < info.stack.length()) {
12868                             pw.print("        ");
12869                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12870                             pw.println();
12871                         }
12872                     }
12873                 }
12874             }
12875         }
12876
12877         if (dumpPackage == null) {
12878             pw.println();
12879             needSep = false;
12880             pw.println("  mStartedUsers:");
12881             for (int i=0; i<mStartedUsers.size(); i++) {
12882                 UserStartedState uss = mStartedUsers.valueAt(i);
12883                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12884                         pw.print(": "); uss.dump("", pw);
12885             }
12886             pw.print("  mStartedUserArray: [");
12887             for (int i=0; i<mStartedUserArray.length; i++) {
12888                 if (i > 0) pw.print(", ");
12889                 pw.print(mStartedUserArray[i]);
12890             }
12891             pw.println("]");
12892             pw.print("  mUserLru: [");
12893             for (int i=0; i<mUserLru.size(); i++) {
12894                 if (i > 0) pw.print(", ");
12895                 pw.print(mUserLru.get(i));
12896             }
12897             pw.println("]");
12898             if (dumpAll) {
12899                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12900             }
12901             synchronized (mUserProfileGroupIdsSelfLocked) {
12902                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12903                     pw.println("  mUserProfileGroupIds:");
12904                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12905                         pw.print("    User #");
12906                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12907                         pw.print(" -> profile #");
12908                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12909                     }
12910                 }
12911             }
12912         }
12913         if (mHomeProcess != null && (dumpPackage == null
12914                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12915             if (needSep) {
12916                 pw.println();
12917                 needSep = false;
12918             }
12919             pw.println("  mHomeProcess: " + mHomeProcess);
12920         }
12921         if (mPreviousProcess != null && (dumpPackage == null
12922                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12923             if (needSep) {
12924                 pw.println();
12925                 needSep = false;
12926             }
12927             pw.println("  mPreviousProcess: " + mPreviousProcess);
12928         }
12929         if (dumpAll) {
12930             StringBuilder sb = new StringBuilder(128);
12931             sb.append("  mPreviousProcessVisibleTime: ");
12932             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12933             pw.println(sb);
12934         }
12935         if (mHeavyWeightProcess != null && (dumpPackage == null
12936                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12937             if (needSep) {
12938                 pw.println();
12939                 needSep = false;
12940             }
12941             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12942         }
12943         if (dumpPackage == null) {
12944             pw.println("  mConfiguration: " + mConfiguration);
12945         }
12946         if (dumpAll) {
12947             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12948             if (mCompatModePackages.getPackages().size() > 0) {
12949                 boolean printed = false;
12950                 for (Map.Entry<String, Integer> entry
12951                         : mCompatModePackages.getPackages().entrySet()) {
12952                     String pkg = entry.getKey();
12953                     int mode = entry.getValue();
12954                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12955                         continue;
12956                     }
12957                     if (!printed) {
12958                         pw.println("  mScreenCompatPackages:");
12959                         printed = true;
12960                     }
12961                     pw.print("    "); pw.print(pkg); pw.print(": ");
12962                             pw.print(mode); pw.println();
12963                 }
12964             }
12965         }
12966         if (dumpPackage == null) {
12967             pw.println("  mWakefulness="
12968                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
12969             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown=" + mLockScreenShown);
12970             pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12971         }
12972         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12973                 || mOrigWaitForDebugger) {
12974             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12975                     || dumpPackage.equals(mOrigDebugApp)) {
12976                 if (needSep) {
12977                     pw.println();
12978                     needSep = false;
12979                 }
12980                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12981                         + " mDebugTransient=" + mDebugTransient
12982                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12983             }
12984         }
12985         if (mOpenGlTraceApp != null) {
12986             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12987                 if (needSep) {
12988                     pw.println();
12989                     needSep = false;
12990                 }
12991                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12992             }
12993         }
12994         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12995                 || mProfileFd != null) {
12996             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12997                 if (needSep) {
12998                     pw.println();
12999                     needSep = false;
13000                 }
13001                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13002                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13003                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13004                         + mAutoStopProfiler);
13005                 pw.println("  mProfileType=" + mProfileType);
13006             }
13007         }
13008         if (dumpPackage == null) {
13009             if (mAlwaysFinishActivities || mController != null) {
13010                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13011                         + " mController=" + mController);
13012             }
13013             if (dumpAll) {
13014                 pw.println("  Total persistent processes: " + numPers);
13015                 pw.println("  mProcessesReady=" + mProcessesReady
13016                         + " mSystemReady=" + mSystemReady
13017                         + " mBooted=" + mBooted
13018                         + " mFactoryTest=" + mFactoryTest);
13019                 pw.println("  mBooting=" + mBooting
13020                         + " mCallFinishBooting=" + mCallFinishBooting
13021                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13022                 pw.print("  mLastPowerCheckRealtime=");
13023                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13024                         pw.println("");
13025                 pw.print("  mLastPowerCheckUptime=");
13026                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13027                         pw.println("");
13028                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13029                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13030                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13031                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13032                         + " (" + mLruProcesses.size() + " total)"
13033                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13034                         + " mNumServiceProcs=" + mNumServiceProcs
13035                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13036                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13037                         + " mLastMemoryLevel" + mLastMemoryLevel
13038                         + " mLastNumProcesses" + mLastNumProcesses);
13039                 long now = SystemClock.uptimeMillis();
13040                 pw.print("  mLastIdleTime=");
13041                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13042                         pw.print(" mLowRamSinceLastIdle=");
13043                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13044                         pw.println();
13045             }
13046         }
13047
13048         if (!printedAnything) {
13049             pw.println("  (nothing)");
13050         }
13051     }
13052
13053     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13054             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13055         if (mProcessesToGc.size() > 0) {
13056             boolean printed = false;
13057             long now = SystemClock.uptimeMillis();
13058             for (int i=0; i<mProcessesToGc.size(); i++) {
13059                 ProcessRecord proc = mProcessesToGc.get(i);
13060                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13061                     continue;
13062                 }
13063                 if (!printed) {
13064                     if (needSep) pw.println();
13065                     needSep = true;
13066                     pw.println("  Processes that are waiting to GC:");
13067                     printed = true;
13068                 }
13069                 pw.print("    Process "); pw.println(proc);
13070                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13071                         pw.print(", last gced=");
13072                         pw.print(now-proc.lastRequestedGc);
13073                         pw.print(" ms ago, last lowMem=");
13074                         pw.print(now-proc.lastLowMemory);
13075                         pw.println(" ms ago");
13076
13077             }
13078         }
13079         return needSep;
13080     }
13081
13082     void printOomLevel(PrintWriter pw, String name, int adj) {
13083         pw.print("    ");
13084         if (adj >= 0) {
13085             pw.print(' ');
13086             if (adj < 10) pw.print(' ');
13087         } else {
13088             if (adj > -10) pw.print(' ');
13089         }
13090         pw.print(adj);
13091         pw.print(": ");
13092         pw.print(name);
13093         pw.print(" (");
13094         pw.print(mProcessList.getMemLevel(adj)/1024);
13095         pw.println(" kB)");
13096     }
13097
13098     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13099             int opti, boolean dumpAll) {
13100         boolean needSep = false;
13101
13102         if (mLruProcesses.size() > 0) {
13103             if (needSep) pw.println();
13104             needSep = true;
13105             pw.println("  OOM levels:");
13106             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13107             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13108             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13109             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13110             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13111             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13112             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13113             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13114             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13115             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13116             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13117             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13118             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13119             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13120
13121             if (needSep) pw.println();
13122             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13123                     pw.print(" total, non-act at ");
13124                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13125                     pw.print(", non-svc at ");
13126                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13127                     pw.println("):");
13128             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13129             needSep = true;
13130         }
13131
13132         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13133
13134         pw.println();
13135         pw.println("  mHomeProcess: " + mHomeProcess);
13136         pw.println("  mPreviousProcess: " + mPreviousProcess);
13137         if (mHeavyWeightProcess != null) {
13138             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13139         }
13140
13141         return true;
13142     }
13143
13144     /**
13145      * There are three ways to call this:
13146      *  - no provider specified: dump all the providers
13147      *  - a flattened component name that matched an existing provider was specified as the
13148      *    first arg: dump that one provider
13149      *  - the first arg isn't the flattened component name of an existing provider:
13150      *    dump all providers whose component contains the first arg as a substring
13151      */
13152     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13153             int opti, boolean dumpAll) {
13154         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13155     }
13156
13157     static class ItemMatcher {
13158         ArrayList<ComponentName> components;
13159         ArrayList<String> strings;
13160         ArrayList<Integer> objects;
13161         boolean all;
13162         
13163         ItemMatcher() {
13164             all = true;
13165         }
13166
13167         void build(String name) {
13168             ComponentName componentName = ComponentName.unflattenFromString(name);
13169             if (componentName != null) {
13170                 if (components == null) {
13171                     components = new ArrayList<ComponentName>();
13172                 }
13173                 components.add(componentName);
13174                 all = false;
13175             } else {
13176                 int objectId = 0;
13177                 // Not a '/' separated full component name; maybe an object ID?
13178                 try {
13179                     objectId = Integer.parseInt(name, 16);
13180                     if (objects == null) {
13181                         objects = new ArrayList<Integer>();
13182                     }
13183                     objects.add(objectId);
13184                     all = false;
13185                 } catch (RuntimeException e) {
13186                     // Not an integer; just do string match.
13187                     if (strings == null) {
13188                         strings = new ArrayList<String>();
13189                     }
13190                     strings.add(name);
13191                     all = false;
13192                 }
13193             }
13194         }
13195
13196         int build(String[] args, int opti) {
13197             for (; opti<args.length; opti++) {
13198                 String name = args[opti];
13199                 if ("--".equals(name)) {
13200                     return opti+1;
13201                 }
13202                 build(name);
13203             }
13204             return opti;
13205         }
13206
13207         boolean match(Object object, ComponentName comp) {
13208             if (all) {
13209                 return true;
13210             }
13211             if (components != null) {
13212                 for (int i=0; i<components.size(); i++) {
13213                     if (components.get(i).equals(comp)) {
13214                         return true;
13215                     }
13216                 }
13217             }
13218             if (objects != null) {
13219                 for (int i=0; i<objects.size(); i++) {
13220                     if (System.identityHashCode(object) == objects.get(i)) {
13221                         return true;
13222                     }
13223                 }
13224             }
13225             if (strings != null) {
13226                 String flat = comp.flattenToString();
13227                 for (int i=0; i<strings.size(); i++) {
13228                     if (flat.contains(strings.get(i))) {
13229                         return true;
13230                     }
13231                 }
13232             }
13233             return false;
13234         }
13235     }
13236
13237     /**
13238      * There are three things that cmd can be:
13239      *  - a flattened component name that matches an existing activity
13240      *  - the cmd arg isn't the flattened component name of an existing activity:
13241      *    dump all activity whose component contains the cmd as a substring
13242      *  - A hex number of the ActivityRecord object instance.
13243      */
13244     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13245             int opti, boolean dumpAll) {
13246         ArrayList<ActivityRecord> activities;
13247         
13248         synchronized (this) {
13249             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13250         }
13251
13252         if (activities.size() <= 0) {
13253             return false;
13254         }
13255
13256         String[] newArgs = new String[args.length - opti];
13257         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13258
13259         TaskRecord lastTask = null;
13260         boolean needSep = false;
13261         for (int i=activities.size()-1; i>=0; i--) {
13262             ActivityRecord r = activities.get(i);
13263             if (needSep) {
13264                 pw.println();
13265             }
13266             needSep = true;
13267             synchronized (this) {
13268                 if (lastTask != r.task) {
13269                     lastTask = r.task;
13270                     pw.print("TASK "); pw.print(lastTask.affinity);
13271                             pw.print(" id="); pw.println(lastTask.taskId);
13272                     if (dumpAll) {
13273                         lastTask.dump(pw, "  ");
13274                     }
13275                 }
13276             }
13277             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13278         }
13279         return true;
13280     }
13281
13282     /**
13283      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13284      * there is a thread associated with the activity.
13285      */
13286     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13287             final ActivityRecord r, String[] args, boolean dumpAll) {
13288         String innerPrefix = prefix + "  ";
13289         synchronized (this) {
13290             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13291                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13292                     pw.print(" pid=");
13293                     if (r.app != null) pw.println(r.app.pid);
13294                     else pw.println("(not running)");
13295             if (dumpAll) {
13296                 r.dump(pw, innerPrefix);
13297             }
13298         }
13299         if (r.app != null && r.app.thread != null) {
13300             // flush anything that is already in the PrintWriter since the thread is going
13301             // to write to the file descriptor directly
13302             pw.flush();
13303             try {
13304                 TransferPipe tp = new TransferPipe();
13305                 try {
13306                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13307                             r.appToken, innerPrefix, args);
13308                     tp.go(fd);
13309                 } finally {
13310                     tp.kill();
13311                 }
13312             } catch (IOException e) {
13313                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13314             } catch (RemoteException e) {
13315                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13316             }
13317         }
13318     }
13319
13320     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13321             int opti, boolean dumpAll, String dumpPackage) {
13322         boolean needSep = false;
13323         boolean onlyHistory = false;
13324         boolean printedAnything = false;
13325
13326         if ("history".equals(dumpPackage)) {
13327             if (opti < args.length && "-s".equals(args[opti])) {
13328                 dumpAll = false;
13329             }
13330             onlyHistory = true;
13331             dumpPackage = null;
13332         }
13333
13334         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13335         if (!onlyHistory && dumpAll) {
13336             if (mRegisteredReceivers.size() > 0) {
13337                 boolean printed = false;
13338                 Iterator it = mRegisteredReceivers.values().iterator();
13339                 while (it.hasNext()) {
13340                     ReceiverList r = (ReceiverList)it.next();
13341                     if (dumpPackage != null && (r.app == null ||
13342                             !dumpPackage.equals(r.app.info.packageName))) {
13343                         continue;
13344                     }
13345                     if (!printed) {
13346                         pw.println("  Registered Receivers:");
13347                         needSep = true;
13348                         printed = true;
13349                         printedAnything = true;
13350                     }
13351                     pw.print("  * "); pw.println(r);
13352                     r.dump(pw, "    ");
13353                 }
13354             }
13355
13356             if (mReceiverResolver.dump(pw, needSep ?
13357                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13358                     "    ", dumpPackage, false)) {
13359                 needSep = true;
13360                 printedAnything = true;
13361             }
13362         }
13363
13364         for (BroadcastQueue q : mBroadcastQueues) {
13365             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13366             printedAnything |= needSep;
13367         }
13368
13369         needSep = true;
13370         
13371         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13372             for (int user=0; user<mStickyBroadcasts.size(); user++) {
13373                 if (needSep) {
13374                     pw.println();
13375                 }
13376                 needSep = true;
13377                 printedAnything = true;
13378                 pw.print("  Sticky broadcasts for user ");
13379                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13380                 StringBuilder sb = new StringBuilder(128);
13381                 for (Map.Entry<String, ArrayList<Intent>> ent
13382                         : mStickyBroadcasts.valueAt(user).entrySet()) {
13383                     pw.print("  * Sticky action "); pw.print(ent.getKey());
13384                     if (dumpAll) {
13385                         pw.println(":");
13386                         ArrayList<Intent> intents = ent.getValue();
13387                         final int N = intents.size();
13388                         for (int i=0; i<N; i++) {
13389                             sb.setLength(0);
13390                             sb.append("    Intent: ");
13391                             intents.get(i).toShortString(sb, false, true, false, false);
13392                             pw.println(sb.toString());
13393                             Bundle bundle = intents.get(i).getExtras();
13394                             if (bundle != null) {
13395                                 pw.print("      ");
13396                                 pw.println(bundle.toString());
13397                             }
13398                         }
13399                     } else {
13400                         pw.println("");
13401                     }
13402                 }
13403             }
13404         }
13405         
13406         if (!onlyHistory && dumpAll) {
13407             pw.println();
13408             for (BroadcastQueue queue : mBroadcastQueues) {
13409                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13410                         + queue.mBroadcastsScheduled);
13411             }
13412             pw.println("  mHandler:");
13413             mHandler.dump(new PrintWriterPrinter(pw), "    ");
13414             needSep = true;
13415             printedAnything = true;
13416         }
13417         
13418         if (!printedAnything) {
13419             pw.println("  (nothing)");
13420         }
13421     }
13422
13423     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13424             int opti, boolean dumpAll, String dumpPackage) {
13425         boolean needSep;
13426         boolean printedAnything = false;
13427
13428         ItemMatcher matcher = new ItemMatcher();
13429         matcher.build(args, opti);
13430
13431         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13432
13433         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13434         printedAnything |= needSep;
13435
13436         if (mLaunchingProviders.size() > 0) {
13437             boolean printed = false;
13438             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13439                 ContentProviderRecord r = mLaunchingProviders.get(i);
13440                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13441                     continue;
13442                 }
13443                 if (!printed) {
13444                     if (needSep) pw.println();
13445                     needSep = true;
13446                     pw.println("  Launching content providers:");
13447                     printed = true;
13448                     printedAnything = true;
13449                 }
13450                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
13451                         pw.println(r);
13452             }
13453         }
13454
13455         if (mGrantedUriPermissions.size() > 0) {
13456             boolean printed = false;
13457             int dumpUid = -2;
13458             if (dumpPackage != null) {
13459                 try {
13460                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13461                 } catch (NameNotFoundException e) {
13462                     dumpUid = -1;
13463                 }
13464             }
13465             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13466                 int uid = mGrantedUriPermissions.keyAt(i);
13467                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13468                     continue;
13469                 }
13470                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13471                 if (!printed) {
13472                     if (needSep) pw.println();
13473                     needSep = true;
13474                     pw.println("  Granted Uri Permissions:");
13475                     printed = true;
13476                     printedAnything = true;
13477                 }
13478                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13479                 for (UriPermission perm : perms.values()) {
13480                     pw.print("    "); pw.println(perm);
13481                     if (dumpAll) {
13482                         perm.dump(pw, "      ");
13483                     }
13484                 }
13485             }
13486         }
13487
13488         if (!printedAnything) {
13489             pw.println("  (nothing)");
13490         }
13491     }
13492
13493     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13494             int opti, boolean dumpAll, String dumpPackage) {
13495         boolean printed = false;
13496
13497         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13498
13499         if (mIntentSenderRecords.size() > 0) {
13500             Iterator<WeakReference<PendingIntentRecord>> it
13501                     = mIntentSenderRecords.values().iterator();
13502             while (it.hasNext()) {
13503                 WeakReference<PendingIntentRecord> ref = it.next();
13504                 PendingIntentRecord rec = ref != null ? ref.get(): null;
13505                 if (dumpPackage != null && (rec == null
13506                         || !dumpPackage.equals(rec.key.packageName))) {
13507                     continue;
13508                 }
13509                 printed = true;
13510                 if (rec != null) {
13511                     pw.print("  * "); pw.println(rec);
13512                     if (dumpAll) {
13513                         rec.dump(pw, "    ");
13514                     }
13515                 } else {
13516                     pw.print("  * "); pw.println(ref);
13517                 }
13518             }
13519         }
13520
13521         if (!printed) {
13522             pw.println("  (nothing)");
13523         }
13524     }
13525
13526     private static final int dumpProcessList(PrintWriter pw,
13527             ActivityManagerService service, List list,
13528             String prefix, String normalLabel, String persistentLabel,
13529             String dumpPackage) {
13530         int numPers = 0;
13531         final int N = list.size()-1;
13532         for (int i=N; i>=0; i--) {
13533             ProcessRecord r = (ProcessRecord)list.get(i);
13534             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13535                 continue;
13536             }
13537             pw.println(String.format("%s%s #%2d: %s",
13538                     prefix, (r.persistent ? persistentLabel : normalLabel),
13539                     i, r.toString()));
13540             if (r.persistent) {
13541                 numPers++;
13542             }
13543         }
13544         return numPers;
13545     }
13546
13547     private static final boolean dumpProcessOomList(PrintWriter pw,
13548             ActivityManagerService service, List<ProcessRecord> origList,
13549             String prefix, String normalLabel, String persistentLabel,
13550             boolean inclDetails, String dumpPackage) {
13551
13552         ArrayList<Pair<ProcessRecord, Integer>> list
13553                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13554         for (int i=0; i<origList.size(); i++) {
13555             ProcessRecord r = origList.get(i);
13556             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13557                 continue;
13558             }
13559             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13560         }
13561
13562         if (list.size() <= 0) {
13563             return false;
13564         }
13565
13566         Comparator<Pair<ProcessRecord, Integer>> comparator
13567                 = new Comparator<Pair<ProcessRecord, Integer>>() {
13568             @Override
13569             public int compare(Pair<ProcessRecord, Integer> object1,
13570                     Pair<ProcessRecord, Integer> object2) {
13571                 if (object1.first.setAdj != object2.first.setAdj) {
13572                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13573                 }
13574                 if (object1.second.intValue() != object2.second.intValue()) {
13575                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13576                 }
13577                 return 0;
13578             }
13579         };
13580
13581         Collections.sort(list, comparator);
13582
13583         final long curRealtime = SystemClock.elapsedRealtime();
13584         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13585         final long curUptime = SystemClock.uptimeMillis();
13586         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13587
13588         for (int i=list.size()-1; i>=0; i--) {
13589             ProcessRecord r = list.get(i).first;
13590             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13591             char schedGroup;
13592             switch (r.setSchedGroup) {
13593                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13594                     schedGroup = 'B';
13595                     break;
13596                 case Process.THREAD_GROUP_DEFAULT:
13597                     schedGroup = 'F';
13598                     break;
13599                 default:
13600                     schedGroup = '?';
13601                     break;
13602             }
13603             char foreground;
13604             if (r.foregroundActivities) {
13605                 foreground = 'A';
13606             } else if (r.foregroundServices) {
13607                 foreground = 'S';
13608             } else {
13609                 foreground = ' ';
13610             }
13611             String procState = ProcessList.makeProcStateString(r.curProcState);
13612             pw.print(prefix);
13613             pw.print(r.persistent ? persistentLabel : normalLabel);
13614             pw.print(" #");
13615             int num = (origList.size()-1)-list.get(i).second;
13616             if (num < 10) pw.print(' ');
13617             pw.print(num);
13618             pw.print(": ");
13619             pw.print(oomAdj);
13620             pw.print(' ');
13621             pw.print(schedGroup);
13622             pw.print('/');
13623             pw.print(foreground);
13624             pw.print('/');
13625             pw.print(procState);
13626             pw.print(" trm:");
13627             if (r.trimMemoryLevel < 10) pw.print(' ');
13628             pw.print(r.trimMemoryLevel);
13629             pw.print(' ');
13630             pw.print(r.toShortString());
13631             pw.print(" (");
13632             pw.print(r.adjType);
13633             pw.println(')');
13634             if (r.adjSource != null || r.adjTarget != null) {
13635                 pw.print(prefix);
13636                 pw.print("    ");
13637                 if (r.adjTarget instanceof ComponentName) {
13638                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13639                 } else if (r.adjTarget != null) {
13640                     pw.print(r.adjTarget.toString());
13641                 } else {
13642                     pw.print("{null}");
13643                 }
13644                 pw.print("<=");
13645                 if (r.adjSource instanceof ProcessRecord) {
13646                     pw.print("Proc{");
13647                     pw.print(((ProcessRecord)r.adjSource).toShortString());
13648                     pw.println("}");
13649                 } else if (r.adjSource != null) {
13650                     pw.println(r.adjSource.toString());
13651                 } else {
13652                     pw.println("{null}");
13653                 }
13654             }
13655             if (inclDetails) {
13656                 pw.print(prefix);
13657                 pw.print("    ");
13658                 pw.print("oom: max="); pw.print(r.maxAdj);
13659                 pw.print(" curRaw="); pw.print(r.curRawAdj);
13660                 pw.print(" setRaw="); pw.print(r.setRawAdj);
13661                 pw.print(" cur="); pw.print(r.curAdj);
13662                 pw.print(" set="); pw.println(r.setAdj);
13663                 pw.print(prefix);
13664                 pw.print("    ");
13665                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13666                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13667                 pw.print(" lastPss="); pw.print(r.lastPss);
13668                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13669                 pw.print(prefix);
13670                 pw.print("    ");
13671                 pw.print("cached="); pw.print(r.cached);
13672                 pw.print(" empty="); pw.print(r.empty);
13673                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13674
13675                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13676                     if (r.lastWakeTime != 0) {
13677                         long wtime;
13678                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13679                         synchronized (stats) {
13680                             wtime = stats.getProcessWakeTime(r.info.uid,
13681                                     r.pid, curRealtime);
13682                         }
13683                         long timeUsed = wtime - r.lastWakeTime;
13684                         pw.print(prefix);
13685                         pw.print("    ");
13686                         pw.print("keep awake over ");
13687                         TimeUtils.formatDuration(realtimeSince, pw);
13688                         pw.print(" used ");
13689                         TimeUtils.formatDuration(timeUsed, pw);
13690                         pw.print(" (");
13691                         pw.print((timeUsed*100)/realtimeSince);
13692                         pw.println("%)");
13693                     }
13694                     if (r.lastCpuTime != 0) {
13695                         long timeUsed = r.curCpuTime - r.lastCpuTime;
13696                         pw.print(prefix);
13697                         pw.print("    ");
13698                         pw.print("run cpu over ");
13699                         TimeUtils.formatDuration(uptimeSince, pw);
13700                         pw.print(" used ");
13701                         TimeUtils.formatDuration(timeUsed, pw);
13702                         pw.print(" (");
13703                         pw.print((timeUsed*100)/uptimeSince);
13704                         pw.println("%)");
13705                     }
13706                 }
13707             }
13708         }
13709         return true;
13710     }
13711
13712     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13713             String[] args) {
13714         ArrayList<ProcessRecord> procs;
13715         synchronized (this) {
13716             if (args != null && args.length > start
13717                     && args[start].charAt(0) != '-') {
13718                 procs = new ArrayList<ProcessRecord>();
13719                 int pid = -1;
13720                 try {
13721                     pid = Integer.parseInt(args[start]);
13722                 } catch (NumberFormatException e) {
13723                 }
13724                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13725                     ProcessRecord proc = mLruProcesses.get(i);
13726                     if (proc.pid == pid) {
13727                         procs.add(proc);
13728                     } else if (allPkgs && proc.pkgList != null
13729                             && proc.pkgList.containsKey(args[start])) {
13730                         procs.add(proc);
13731                     } else if (proc.processName.equals(args[start])) {
13732                         procs.add(proc);
13733                     }
13734                 }
13735                 if (procs.size() <= 0) {
13736                     return null;
13737                 }
13738             } else {
13739                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13740             }
13741         }
13742         return procs;
13743     }
13744
13745     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13746             PrintWriter pw, String[] args) {
13747         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13748         if (procs == null) {
13749             pw.println("No process found for: " + args[0]);
13750             return;
13751         }
13752
13753         long uptime = SystemClock.uptimeMillis();
13754         long realtime = SystemClock.elapsedRealtime();
13755         pw.println("Applications Graphics Acceleration Info:");
13756         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13757         
13758         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13759             ProcessRecord r = procs.get(i);
13760             if (r.thread != null) {
13761                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13762                 pw.flush();
13763                 try {
13764                     TransferPipe tp = new TransferPipe();
13765                     try {
13766                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13767                         tp.go(fd);
13768                     } finally {
13769                         tp.kill();
13770                     }
13771                 } catch (IOException e) {
13772                     pw.println("Failure while dumping the app: " + r);
13773                     pw.flush();
13774                 } catch (RemoteException e) {
13775                     pw.println("Got a RemoteException while dumping the app " + r);
13776                     pw.flush();
13777                 }
13778             }
13779         }
13780     }
13781
13782     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13783         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13784         if (procs == null) {
13785             pw.println("No process found for: " + args[0]);
13786             return;
13787         }
13788
13789         pw.println("Applications Database Info:");
13790
13791         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13792             ProcessRecord r = procs.get(i);
13793             if (r.thread != null) {
13794                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13795                 pw.flush();
13796                 try {
13797                     TransferPipe tp = new TransferPipe();
13798                     try {
13799                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13800                         tp.go(fd);
13801                     } finally {
13802                         tp.kill();
13803                     }
13804                 } catch (IOException e) {
13805                     pw.println("Failure while dumping the app: " + r);
13806                     pw.flush();
13807                 } catch (RemoteException e) {
13808                     pw.println("Got a RemoteException while dumping the app " + r);
13809                     pw.flush();
13810                 }
13811             }
13812         }
13813     }
13814
13815     final static class MemItem {
13816         final boolean isProc;
13817         final String label;
13818         final String shortLabel;
13819         final long pss;
13820         final int id;
13821         final boolean hasActivities;
13822         ArrayList<MemItem> subitems;
13823
13824         public MemItem(String _label, String _shortLabel, long _pss, int _id,
13825                 boolean _hasActivities) {
13826             isProc = true;
13827             label = _label;
13828             shortLabel = _shortLabel;
13829             pss = _pss;
13830             id = _id;
13831             hasActivities = _hasActivities;
13832         }
13833
13834         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13835             isProc = false;
13836             label = _label;
13837             shortLabel = _shortLabel;
13838             pss = _pss;
13839             id = _id;
13840             hasActivities = false;
13841         }
13842     }
13843
13844     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13845             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13846         if (sort && !isCompact) {
13847             Collections.sort(items, new Comparator<MemItem>() {
13848                 @Override
13849                 public int compare(MemItem lhs, MemItem rhs) {
13850                     if (lhs.pss < rhs.pss) {
13851                         return 1;
13852                     } else if (lhs.pss > rhs.pss) {
13853                         return -1;
13854                     }
13855                     return 0;
13856                 }
13857             });
13858         }
13859
13860         for (int i=0; i<items.size(); i++) {
13861             MemItem mi = items.get(i);
13862             if (!isCompact) {
13863                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13864             } else if (mi.isProc) {
13865                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13866                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13867                 pw.println(mi.hasActivities ? ",a" : ",e");
13868             } else {
13869                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13870                 pw.println(mi.pss);
13871             }
13872             if (mi.subitems != null) {
13873                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13874                         true, isCompact);
13875             }
13876         }
13877     }
13878
13879     // These are in KB.
13880     static final long[] DUMP_MEM_BUCKETS = new long[] {
13881         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13882         120*1024, 160*1024, 200*1024,
13883         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13884         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13885     };
13886
13887     static final void appendMemBucket(StringBuilder out, long memKB, String label,
13888             boolean stackLike) {
13889         int start = label.lastIndexOf('.');
13890         if (start >= 0) start++;
13891         else start = 0;
13892         int end = label.length();
13893         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13894             if (DUMP_MEM_BUCKETS[i] >= memKB) {
13895                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
13896                 out.append(bucket);
13897                 out.append(stackLike ? "MB." : "MB ");
13898                 out.append(label, start, end);
13899                 return;
13900             }
13901         }
13902         out.append(memKB/1024);
13903         out.append(stackLike ? "MB." : "MB ");
13904         out.append(label, start, end);
13905     }
13906
13907     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13908             ProcessList.NATIVE_ADJ,
13909             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13910             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13911             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13912             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13913             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13914             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13915     };
13916     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13917             "Native",
13918             "System", "Persistent", "Persistent Service", "Foreground",
13919             "Visible", "Perceptible",
13920             "Heavy Weight", "Backup",
13921             "A Services", "Home",
13922             "Previous", "B Services", "Cached"
13923     };
13924     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13925             "native",
13926             "sys", "pers", "persvc", "fore",
13927             "vis", "percept",
13928             "heavy", "backup",
13929             "servicea", "home",
13930             "prev", "serviceb", "cached"
13931     };
13932
13933     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13934             long realtime, boolean isCheckinRequest, boolean isCompact) {
13935         if (isCheckinRequest || isCompact) {
13936             // short checkin version
13937             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13938         } else {
13939             pw.println("Applications Memory Usage (kB):");
13940             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13941         }
13942     }
13943
13944     final void dumpApplicationMemoryUsage(FileDescriptor fd,
13945             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13946         boolean dumpDetails = false;
13947         boolean dumpFullDetails = false;
13948         boolean dumpDalvik = false;
13949         boolean oomOnly = false;
13950         boolean isCompact = false;
13951         boolean localOnly = false;
13952         boolean packages = false;
13953         
13954         int opti = 0;
13955         while (opti < args.length) {
13956             String opt = args[opti];
13957             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13958                 break;
13959             }
13960             opti++;
13961             if ("-a".equals(opt)) {
13962                 dumpDetails = true;
13963                 dumpFullDetails = true;
13964                 dumpDalvik = true;
13965             } else if ("-d".equals(opt)) {
13966                 dumpDalvik = true;
13967             } else if ("-c".equals(opt)) {
13968                 isCompact = true;
13969             } else if ("--oom".equals(opt)) {
13970                 oomOnly = true;
13971             } else if ("--local".equals(opt)) {
13972                 localOnly = true;
13973             } else if ("--package".equals(opt)) {
13974                 packages = true;
13975             } else if ("-h".equals(opt)) {
13976                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13977                 pw.println("  -a: include all available information for each process.");
13978                 pw.println("  -d: include dalvik details when dumping process details.");
13979                 pw.println("  -c: dump in a compact machine-parseable representation.");
13980                 pw.println("  --oom: only show processes organized by oom adj.");
13981                 pw.println("  --local: only collect details locally, don't call process.");
13982                 pw.println("  --package: interpret process arg as package, dumping all");
13983                 pw.println("             processes that have loaded that package.");
13984                 pw.println("If [process] is specified it can be the name or ");
13985                 pw.println("pid of a specific process to dump.");
13986                 return;
13987             } else {
13988                 pw.println("Unknown argument: " + opt + "; use -h for help");
13989             }
13990         }
13991         
13992         final boolean isCheckinRequest = scanArgs(args, "--checkin");
13993         long uptime = SystemClock.uptimeMillis();
13994         long realtime = SystemClock.elapsedRealtime();
13995         final long[] tmpLong = new long[1];
13996
13997         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13998         if (procs == null) {
13999             // No Java processes.  Maybe they want to print a native process.
14000             if (args != null && args.length > opti
14001                     && args[opti].charAt(0) != '-') {
14002                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14003                         = new ArrayList<ProcessCpuTracker.Stats>();
14004                 updateCpuStatsNow();
14005                 int findPid = -1;
14006                 try {
14007                     findPid = Integer.parseInt(args[opti]);
14008                 } catch (NumberFormatException e) {
14009                 }
14010                 synchronized (mProcessCpuTracker) {
14011                     final int N = mProcessCpuTracker.countStats();
14012                     for (int i=0; i<N; i++) {
14013                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14014                         if (st.pid == findPid || (st.baseName != null
14015                                 && st.baseName.equals(args[opti]))) {
14016                             nativeProcs.add(st);
14017                         }
14018                     }
14019                 }
14020                 if (nativeProcs.size() > 0) {
14021                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14022                             isCompact);
14023                     Debug.MemoryInfo mi = null;
14024                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14025                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14026                         final int pid = r.pid;
14027                         if (!isCheckinRequest && dumpDetails) {
14028                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14029                         }
14030                         if (mi == null) {
14031                             mi = new Debug.MemoryInfo();
14032                         }
14033                         if (dumpDetails || (!brief && !oomOnly)) {
14034                             Debug.getMemoryInfo(pid, mi);
14035                         } else {
14036                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14037                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14038                         }
14039                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14040                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14041                         if (isCheckinRequest) {
14042                             pw.println();
14043                         }
14044                     }
14045                     return;
14046                 }
14047             }
14048             pw.println("No process found for: " + args[opti]);
14049             return;
14050         }
14051
14052         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14053             dumpDetails = true;
14054         }
14055
14056         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14057
14058         String[] innerArgs = new String[args.length-opti];
14059         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14060
14061         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14062         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14063         long nativePss=0, dalvikPss=0, otherPss=0;
14064         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14065
14066         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14067         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14068                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14069
14070         long totalPss = 0;
14071         long cachedPss = 0;
14072
14073         Debug.MemoryInfo mi = null;
14074         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14075             final ProcessRecord r = procs.get(i);
14076             final IApplicationThread thread;
14077             final int pid;
14078             final int oomAdj;
14079             final boolean hasActivities;
14080             synchronized (this) {
14081                 thread = r.thread;
14082                 pid = r.pid;
14083                 oomAdj = r.getSetAdjWithServices();
14084                 hasActivities = r.activities.size() > 0;
14085             }
14086             if (thread != null) {
14087                 if (!isCheckinRequest && dumpDetails) {
14088                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14089                 }
14090                 if (mi == null) {
14091                     mi = new Debug.MemoryInfo();
14092                 }
14093                 if (dumpDetails || (!brief && !oomOnly)) {
14094                     Debug.getMemoryInfo(pid, mi);
14095                 } else {
14096                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14097                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14098                 }
14099                 if (dumpDetails) {
14100                     if (localOnly) {
14101                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14102                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14103                         if (isCheckinRequest) {
14104                             pw.println();
14105                         }
14106                     } else {
14107                         try {
14108                             pw.flush();
14109                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14110                                     dumpDalvik, innerArgs);
14111                         } catch (RemoteException e) {
14112                             if (!isCheckinRequest) {
14113                                 pw.println("Got RemoteException!");
14114                                 pw.flush();
14115                             }
14116                         }
14117                     }
14118                 }
14119
14120                 final long myTotalPss = mi.getTotalPss();
14121                 final long myTotalUss = mi.getTotalUss();
14122
14123                 synchronized (this) {
14124                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14125                         // Record this for posterity if the process has been stable.
14126                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14127                     }
14128                 }
14129
14130                 if (!isCheckinRequest && mi != null) {
14131                     totalPss += myTotalPss;
14132                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14133                             (hasActivities ? " / activities)" : ")"),
14134                             r.processName, myTotalPss, pid, hasActivities);
14135                     procMems.add(pssItem);
14136                     procMemsMap.put(pid, pssItem);
14137
14138                     nativePss += mi.nativePss;
14139                     dalvikPss += mi.dalvikPss;
14140                     otherPss += mi.otherPss;
14141                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14142                         long mem = mi.getOtherPss(j);
14143                         miscPss[j] += mem;
14144                         otherPss -= mem;
14145                     }
14146
14147                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14148                         cachedPss += myTotalPss;
14149                     }
14150
14151                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14152                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14153                                 || oomIndex == (oomPss.length-1)) {
14154                             oomPss[oomIndex] += myTotalPss;
14155                             if (oomProcs[oomIndex] == null) {
14156                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14157                             }
14158                             oomProcs[oomIndex].add(pssItem);
14159                             break;
14160                         }
14161                     }
14162                 }
14163             }
14164         }
14165
14166         long nativeProcTotalPss = 0;
14167
14168         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14169             // If we are showing aggregations, also look for native processes to
14170             // include so that our aggregations are more accurate.
14171             updateCpuStatsNow();
14172             synchronized (mProcessCpuTracker) {
14173                 final int N = mProcessCpuTracker.countStats();
14174                 for (int i=0; i<N; i++) {
14175                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14176                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14177                         if (mi == null) {
14178                             mi = new Debug.MemoryInfo();
14179                         }
14180                         if (!brief && !oomOnly) {
14181                             Debug.getMemoryInfo(st.pid, mi);
14182                         } else {
14183                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14184                             mi.nativePrivateDirty = (int)tmpLong[0];
14185                         }
14186
14187                         final long myTotalPss = mi.getTotalPss();
14188                         totalPss += myTotalPss;
14189                         nativeProcTotalPss += myTotalPss;
14190
14191                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14192                                 st.name, myTotalPss, st.pid, false);
14193                         procMems.add(pssItem);
14194
14195                         nativePss += mi.nativePss;
14196                         dalvikPss += mi.dalvikPss;
14197                         otherPss += mi.otherPss;
14198                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14199                             long mem = mi.getOtherPss(j);
14200                             miscPss[j] += mem;
14201                             otherPss -= mem;
14202                         }
14203                         oomPss[0] += myTotalPss;
14204                         if (oomProcs[0] == null) {
14205                             oomProcs[0] = new ArrayList<MemItem>();
14206                         }
14207                         oomProcs[0].add(pssItem);
14208                     }
14209                 }
14210             }
14211
14212             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14213
14214             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14215             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14216             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14217             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14218                 String label = Debug.MemoryInfo.getOtherLabel(j);
14219                 catMems.add(new MemItem(label, label, miscPss[j], j));
14220             }
14221
14222             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14223             for (int j=0; j<oomPss.length; j++) {
14224                 if (oomPss[j] != 0) {
14225                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14226                             : DUMP_MEM_OOM_LABEL[j];
14227                     MemItem item = new MemItem(label, label, oomPss[j],
14228                             DUMP_MEM_OOM_ADJ[j]);
14229                     item.subitems = oomProcs[j];
14230                     oomMems.add(item);
14231                 }
14232             }
14233
14234             if (!brief && !oomOnly && !isCompact) {
14235                 pw.println();
14236                 pw.println("Total PSS by process:");
14237                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14238                 pw.println();
14239             }
14240             if (!isCompact) {
14241                 pw.println("Total PSS by OOM adjustment:");
14242             }
14243             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14244             if (!brief && !oomOnly) {
14245                 PrintWriter out = categoryPw != null ? categoryPw : pw;
14246                 if (!isCompact) {
14247                     out.println();
14248                     out.println("Total PSS by category:");
14249                 }
14250                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14251             }
14252             if (!isCompact) {
14253                 pw.println();
14254             }
14255             MemInfoReader memInfo = new MemInfoReader();
14256             memInfo.readMemInfo();
14257             if (nativeProcTotalPss > 0) {
14258                 synchronized (this) {
14259                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14260                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14261                             memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14262                             nativeProcTotalPss);
14263                 }
14264             }
14265             if (!brief) {
14266                 if (!isCompact) {
14267                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14268                     pw.print(" kB (status ");
14269                     switch (mLastMemoryLevel) {
14270                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14271                             pw.println("normal)");
14272                             break;
14273                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14274                             pw.println("moderate)");
14275                             break;
14276                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
14277                             pw.println("low)");
14278                             break;
14279                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14280                             pw.println("critical)");
14281                             break;
14282                         default:
14283                             pw.print(mLastMemoryLevel);
14284                             pw.println(")");
14285                             break;
14286                     }
14287                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14288                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
14289                             pw.print(cachedPss); pw.print(" cached pss + ");
14290                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14291                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14292                 } else {
14293                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14294                     pw.print(cachedPss + memInfo.getCachedSizeKb()
14295                             + memInfo.getFreeSizeKb()); pw.print(",");
14296                     pw.println(totalPss - cachedPss);
14297                 }
14298             }
14299             if (!isCompact) {
14300                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14301                         + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14302                         + memInfo.getSlabSizeKb()); pw.print(" kB (");
14303                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14304                         pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14305                         pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14306                         pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14307                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14308                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14309                         - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14310                         - memInfo.getSlabSizeKb()); pw.println(" kB");
14311             }
14312             if (!brief) {
14313                 if (memInfo.getZramTotalSizeKb() != 0) {
14314                     if (!isCompact) {
14315                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14316                                 pw.print(" kB physical used for ");
14317                                 pw.print(memInfo.getSwapTotalSizeKb()
14318                                         - memInfo.getSwapFreeSizeKb());
14319                                 pw.print(" kB in swap (");
14320                                 pw.print(memInfo.getSwapTotalSizeKb());
14321                                 pw.println(" kB total swap)");
14322                     } else {
14323                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14324                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14325                                 pw.println(memInfo.getSwapFreeSizeKb());
14326                     }
14327                 }
14328                 final int[] SINGLE_LONG_FORMAT = new int[] {
14329                     Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14330                 };
14331                 long[] longOut = new long[1];
14332                 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14333                         SINGLE_LONG_FORMAT, null, longOut, null);
14334                 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14335                 longOut[0] = 0;
14336                 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14337                         SINGLE_LONG_FORMAT, null, longOut, null);
14338                 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14339                 longOut[0] = 0;
14340                 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14341                         SINGLE_LONG_FORMAT, null, longOut, null);
14342                 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14343                 longOut[0] = 0;
14344                 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14345                         SINGLE_LONG_FORMAT, null, longOut, null);
14346                 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14347                 if (!isCompact) {
14348                     if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14349                         pw.print("      KSM: "); pw.print(sharing);
14350                                 pw.print(" kB saved from shared ");
14351                                 pw.print(shared); pw.println(" kB");
14352                         pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14353                                 pw.print(voltile); pw.println(" kB volatile");
14354                     }
14355                     pw.print("   Tuning: ");
14356                     pw.print(ActivityManager.staticGetMemoryClass());
14357                     pw.print(" (large ");
14358                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14359                     pw.print("), oom ");
14360                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14361                     pw.print(" kB");
14362                     pw.print(", restore limit ");
14363                     pw.print(mProcessList.getCachedRestoreThresholdKb());
14364                     pw.print(" kB");
14365                     if (ActivityManager.isLowRamDeviceStatic()) {
14366                         pw.print(" (low-ram)");
14367                     }
14368                     if (ActivityManager.isHighEndGfx()) {
14369                         pw.print(" (high-end-gfx)");
14370                     }
14371                     pw.println();
14372                 } else {
14373                     pw.print("ksm,"); pw.print(sharing); pw.print(",");
14374                     pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14375                     pw.println(voltile);
14376                     pw.print("tuning,");
14377                     pw.print(ActivityManager.staticGetMemoryClass());
14378                     pw.print(',');
14379                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14380                     pw.print(',');
14381                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14382                     if (ActivityManager.isLowRamDeviceStatic()) {
14383                         pw.print(",low-ram");
14384                     }
14385                     if (ActivityManager.isHighEndGfx()) {
14386                         pw.print(",high-end-gfx");
14387                     }
14388                     pw.println();
14389                 }
14390             }
14391         }
14392     }
14393
14394     /**
14395      * Searches array of arguments for the specified string
14396      * @param args array of argument strings
14397      * @param value value to search for
14398      * @return true if the value is contained in the array
14399      */
14400     private static boolean scanArgs(String[] args, String value) {
14401         if (args != null) {
14402             for (String arg : args) {
14403                 if (value.equals(arg)) {
14404                     return true;
14405                 }
14406             }
14407         }
14408         return false;
14409     }
14410
14411     private final boolean removeDyingProviderLocked(ProcessRecord proc,
14412             ContentProviderRecord cpr, boolean always) {
14413         final boolean inLaunching = mLaunchingProviders.contains(cpr);
14414
14415         if (!inLaunching || always) {
14416             synchronized (cpr) {
14417                 cpr.launchingApp = null;
14418                 cpr.notifyAll();
14419             }
14420             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14421             String names[] = cpr.info.authority.split(";");
14422             for (int j = 0; j < names.length; j++) {
14423                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14424             }
14425         }
14426
14427         for (int i=0; i<cpr.connections.size(); i++) {
14428             ContentProviderConnection conn = cpr.connections.get(i);
14429             if (conn.waiting) {
14430                 // If this connection is waiting for the provider, then we don't
14431                 // need to mess with its process unless we are always removing
14432                 // or for some reason the provider is not currently launching.
14433                 if (inLaunching && !always) {
14434                     continue;
14435                 }
14436             }
14437             ProcessRecord capp = conn.client;
14438             conn.dead = true;
14439             if (conn.stableCount > 0) {
14440                 if (!capp.persistent && capp.thread != null
14441                         && capp.pid != 0
14442                         && capp.pid != MY_PID) {
14443                     capp.kill("depends on provider "
14444                             + cpr.name.flattenToShortString()
14445                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14446                 }
14447             } else if (capp.thread != null && conn.provider.provider != null) {
14448                 try {
14449                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14450                 } catch (RemoteException e) {
14451                 }
14452                 // In the protocol here, we don't expect the client to correctly
14453                 // clean up this connection, we'll just remove it.
14454                 cpr.connections.remove(i);
14455                 conn.client.conProviders.remove(conn);
14456             }
14457         }
14458
14459         if (inLaunching && always) {
14460             mLaunchingProviders.remove(cpr);
14461         }
14462         return inLaunching;
14463     }
14464
14465     /**
14466      * Main code for cleaning up a process when it has gone away.  This is
14467      * called both as a result of the process dying, or directly when stopping
14468      * a process when running in single process mode.
14469      *
14470      * @return Returns true if the given process has been restarted, so the
14471      * app that was passed in must remain on the process lists.
14472      */
14473     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14474             boolean restarting, boolean allowRestart, int index) {
14475         if (index >= 0) {
14476             removeLruProcessLocked(app);
14477             ProcessList.remove(app.pid);
14478         }
14479
14480         mProcessesToGc.remove(app);
14481         mPendingPssProcesses.remove(app);
14482
14483         // Dismiss any open dialogs.
14484         if (app.crashDialog != null && !app.forceCrashReport) {
14485             app.crashDialog.dismiss();
14486             app.crashDialog = null;
14487         }
14488         if (app.anrDialog != null) {
14489             app.anrDialog.dismiss();
14490             app.anrDialog = null;
14491         }
14492         if (app.waitDialog != null) {
14493             app.waitDialog.dismiss();
14494             app.waitDialog = null;
14495         }
14496
14497         app.crashing = false;
14498         app.notResponding = false;
14499
14500         app.resetPackageList(mProcessStats);
14501         app.unlinkDeathRecipient();
14502         app.makeInactive(mProcessStats);
14503         app.waitingToKill = null;
14504         app.forcingToForeground = null;
14505         updateProcessForegroundLocked(app, false, false);
14506         app.foregroundActivities = false;
14507         app.hasShownUi = false;
14508         app.treatLikeActivity = false;
14509         app.hasAboveClient = false;
14510         app.hasClientActivities = false;
14511
14512         mServices.killServicesLocked(app, allowRestart);
14513
14514         boolean restart = false;
14515
14516         // Remove published content providers.
14517         for (int i=app.pubProviders.size()-1; i>=0; i--) {
14518             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14519             final boolean always = app.bad || !allowRestart;
14520             if (removeDyingProviderLocked(app, cpr, always) || always) {
14521                 // We left the provider in the launching list, need to
14522                 // restart it.
14523                 restart = true;
14524             }
14525
14526             cpr.provider = null;
14527             cpr.proc = null;
14528         }
14529         app.pubProviders.clear();
14530
14531         // Take care of any launching providers waiting for this process.
14532         if (checkAppInLaunchingProvidersLocked(app, false)) {
14533             restart = true;
14534         }
14535
14536         // Unregister from connected content providers.
14537         if (!app.conProviders.isEmpty()) {
14538             for (int i=0; i<app.conProviders.size(); i++) {
14539                 ContentProviderConnection conn = app.conProviders.get(i);
14540                 conn.provider.connections.remove(conn);
14541             }
14542             app.conProviders.clear();
14543         }
14544
14545         // At this point there may be remaining entries in mLaunchingProviders
14546         // where we were the only one waiting, so they are no longer of use.
14547         // Look for these and clean up if found.
14548         // XXX Commented out for now.  Trying to figure out a way to reproduce
14549         // the actual situation to identify what is actually going on.
14550         if (false) {
14551             for (int i=0; i<mLaunchingProviders.size(); i++) {
14552                 ContentProviderRecord cpr = (ContentProviderRecord)
14553                         mLaunchingProviders.get(i);
14554                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14555                     synchronized (cpr) {
14556                         cpr.launchingApp = null;
14557                         cpr.notifyAll();
14558                     }
14559                 }
14560             }
14561         }
14562
14563         skipCurrentReceiverLocked(app);
14564
14565         // Unregister any receivers.
14566         for (int i=app.receivers.size()-1; i>=0; i--) {
14567             removeReceiverLocked(app.receivers.valueAt(i));
14568         }
14569         app.receivers.clear();
14570
14571         // If the app is undergoing backup, tell the backup manager about it
14572         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14573             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14574                     + mBackupTarget.appInfo + " died during backup");
14575             try {
14576                 IBackupManager bm = IBackupManager.Stub.asInterface(
14577                         ServiceManager.getService(Context.BACKUP_SERVICE));
14578                 bm.agentDisconnected(app.info.packageName);
14579             } catch (RemoteException e) {
14580                 // can't happen; backup manager is local
14581             }
14582         }
14583
14584         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14585             ProcessChangeItem item = mPendingProcessChanges.get(i);
14586             if (item.pid == app.pid) {
14587                 mPendingProcessChanges.remove(i);
14588                 mAvailProcessChanges.add(item);
14589             }
14590         }
14591         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14592
14593         // If the caller is restarting this app, then leave it in its
14594         // current lists and let the caller take care of it.
14595         if (restarting) {
14596             return false;
14597         }
14598
14599         if (!app.persistent || app.isolated) {
14600             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14601                     "Removing non-persistent process during cleanup: " + app);
14602             mProcessNames.remove(app.processName, app.uid);
14603             mIsolatedProcesses.remove(app.uid);
14604             if (mHeavyWeightProcess == app) {
14605                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14606                         mHeavyWeightProcess.userId, 0));
14607                 mHeavyWeightProcess = null;
14608             }
14609         } else if (!app.removed) {
14610             // This app is persistent, so we need to keep its record around.
14611             // If it is not already on the pending app list, add it there
14612             // and start a new process for it.
14613             if (mPersistentStartingProcesses.indexOf(app) < 0) {
14614                 mPersistentStartingProcesses.add(app);
14615                 restart = true;
14616             }
14617         }
14618         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14619                 "Clean-up removing on hold: " + app);
14620         mProcessesOnHold.remove(app);
14621
14622         if (app == mHomeProcess) {
14623             mHomeProcess = null;
14624         }
14625         if (app == mPreviousProcess) {
14626             mPreviousProcess = null;
14627         }
14628
14629         if (restart && !app.isolated) {
14630             // We have components that still need to be running in the
14631             // process, so re-launch it.
14632             if (index < 0) {
14633                 ProcessList.remove(app.pid);
14634             }
14635             mProcessNames.put(app.processName, app.uid, app);
14636             startProcessLocked(app, "restart", app.processName);
14637             return true;
14638         } else if (app.pid > 0 && app.pid != MY_PID) {
14639             // Goodbye!
14640             boolean removed;
14641             synchronized (mPidsSelfLocked) {
14642                 mPidsSelfLocked.remove(app.pid);
14643                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14644             }
14645             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14646             if (app.isolated) {
14647                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14648             }
14649             app.setPid(0);
14650         }
14651         return false;
14652     }
14653
14654     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14655         // Look through the content providers we are waiting to have launched,
14656         // and if any run in this process then either schedule a restart of
14657         // the process or kill the client waiting for it if this process has
14658         // gone bad.
14659         int NL = mLaunchingProviders.size();
14660         boolean restart = false;
14661         for (int i=0; i<NL; i++) {
14662             ContentProviderRecord cpr = mLaunchingProviders.get(i);
14663             if (cpr.launchingApp == app) {
14664                 if (!alwaysBad && !app.bad) {
14665                     restart = true;
14666                 } else {
14667                     removeDyingProviderLocked(app, cpr, true);
14668                     // cpr should have been removed from mLaunchingProviders
14669                     NL = mLaunchingProviders.size();
14670                     i--;
14671                 }
14672             }
14673         }
14674         return restart;
14675     }
14676     
14677     // =========================================================
14678     // SERVICES
14679     // =========================================================
14680
14681     @Override
14682     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14683             int flags) {
14684         enforceNotIsolatedCaller("getServices");
14685         synchronized (this) {
14686             return mServices.getRunningServiceInfoLocked(maxNum, flags);
14687         }
14688     }
14689
14690     @Override
14691     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14692         enforceNotIsolatedCaller("getRunningServiceControlPanel");
14693         synchronized (this) {
14694             return mServices.getRunningServiceControlPanelLocked(name);
14695         }
14696     }
14697
14698     @Override
14699     public ComponentName startService(IApplicationThread caller, Intent service,
14700             String resolvedType, int userId) {
14701         enforceNotIsolatedCaller("startService");
14702         // Refuse possible leaked file descriptors
14703         if (service != null && service.hasFileDescriptors() == true) {
14704             throw new IllegalArgumentException("File descriptors passed in Intent");
14705         }
14706
14707         if (DEBUG_SERVICE)
14708             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14709         synchronized(this) {
14710             final int callingPid = Binder.getCallingPid();
14711             final int callingUid = Binder.getCallingUid();
14712             final long origId = Binder.clearCallingIdentity();
14713             ComponentName res = mServices.startServiceLocked(caller, service,
14714                     resolvedType, callingPid, callingUid, userId);
14715             Binder.restoreCallingIdentity(origId);
14716             return res;
14717         }
14718     }
14719
14720     ComponentName startServiceInPackage(int uid,
14721             Intent service, String resolvedType, int userId) {
14722         synchronized(this) {
14723             if (DEBUG_SERVICE)
14724                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14725             final long origId = Binder.clearCallingIdentity();
14726             ComponentName res = mServices.startServiceLocked(null, service,
14727                     resolvedType, -1, uid, userId);
14728             Binder.restoreCallingIdentity(origId);
14729             return res;
14730         }
14731     }
14732
14733     @Override
14734     public int stopService(IApplicationThread caller, Intent service,
14735             String resolvedType, int userId) {
14736         enforceNotIsolatedCaller("stopService");
14737         // Refuse possible leaked file descriptors
14738         if (service != null && service.hasFileDescriptors() == true) {
14739             throw new IllegalArgumentException("File descriptors passed in Intent");
14740         }
14741
14742         synchronized(this) {
14743             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14744         }
14745     }
14746
14747     @Override
14748     public IBinder peekService(Intent service, String resolvedType) {
14749         enforceNotIsolatedCaller("peekService");
14750         // Refuse possible leaked file descriptors
14751         if (service != null && service.hasFileDescriptors() == true) {
14752             throw new IllegalArgumentException("File descriptors passed in Intent");
14753         }
14754         synchronized(this) {
14755             return mServices.peekServiceLocked(service, resolvedType);
14756         }
14757     }
14758     
14759     @Override
14760     public boolean stopServiceToken(ComponentName className, IBinder token,
14761             int startId) {
14762         synchronized(this) {
14763             return mServices.stopServiceTokenLocked(className, token, startId);
14764         }
14765     }
14766
14767     @Override
14768     public void setServiceForeground(ComponentName className, IBinder token,
14769             int id, Notification notification, boolean removeNotification) {
14770         synchronized(this) {
14771             mServices.setServiceForegroundLocked(className, token, id, notification,
14772                     removeNotification);
14773         }
14774     }
14775
14776     @Override
14777     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14778             boolean requireFull, String name, String callerPackage) {
14779         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14780                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14781     }
14782
14783     int unsafeConvertIncomingUser(int userId) {
14784         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14785                 ? mCurrentUserId : userId;
14786     }
14787
14788     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14789             int allowMode, String name, String callerPackage) {
14790         final int callingUserId = UserHandle.getUserId(callingUid);
14791         if (callingUserId == userId) {
14792             return userId;
14793         }
14794
14795         // Note that we may be accessing mCurrentUserId outside of a lock...
14796         // shouldn't be a big deal, if this is being called outside
14797         // of a locked context there is intrinsically a race with
14798         // the value the caller will receive and someone else changing it.
14799         // We assume that USER_CURRENT_OR_SELF will use the current user; later
14800         // we will switch to the calling user if access to the current user fails.
14801         int targetUserId = unsafeConvertIncomingUser(userId);
14802
14803         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14804             final boolean allow;
14805             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14806                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14807                 // If the caller has this permission, they always pass go.  And collect $200.
14808                 allow = true;
14809             } else if (allowMode == ALLOW_FULL_ONLY) {
14810                 // We require full access, sucks to be you.
14811                 allow = false;
14812             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14813                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14814                 // If the caller does not have either permission, they are always doomed.
14815                 allow = false;
14816             } else if (allowMode == ALLOW_NON_FULL) {
14817                 // We are blanket allowing non-full access, you lucky caller!
14818                 allow = true;
14819             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14820                 // We may or may not allow this depending on whether the two users are
14821                 // in the same profile.
14822                 synchronized (mUserProfileGroupIdsSelfLocked) {
14823                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14824                             UserInfo.NO_PROFILE_GROUP_ID);
14825                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14826                             UserInfo.NO_PROFILE_GROUP_ID);
14827                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14828                             && callingProfile == targetProfile;
14829                 }
14830             } else {
14831                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
14832             }
14833             if (!allow) {
14834                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14835                     // In this case, they would like to just execute as their
14836                     // owner user instead of failing.
14837                     targetUserId = callingUserId;
14838                 } else {
14839                     StringBuilder builder = new StringBuilder(128);
14840                     builder.append("Permission Denial: ");
14841                     builder.append(name);
14842                     if (callerPackage != null) {
14843                         builder.append(" from ");
14844                         builder.append(callerPackage);
14845                     }
14846                     builder.append(" asks to run as user ");
14847                     builder.append(userId);
14848                     builder.append(" but is calling from user ");
14849                     builder.append(UserHandle.getUserId(callingUid));
14850                     builder.append("; this requires ");
14851                     builder.append(INTERACT_ACROSS_USERS_FULL);
14852                     if (allowMode != ALLOW_FULL_ONLY) {
14853                         builder.append(" or ");
14854                         builder.append(INTERACT_ACROSS_USERS);
14855                     }
14856                     String msg = builder.toString();
14857                     Slog.w(TAG, msg);
14858                     throw new SecurityException(msg);
14859                 }
14860             }
14861         }
14862         if (!allowAll && targetUserId < 0) {
14863             throw new IllegalArgumentException(
14864                     "Call does not support special user #" + targetUserId);
14865         }
14866         // Check shell permission
14867         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14868             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14869                     targetUserId)) {
14870                 throw new SecurityException("Shell does not have permission to access user "
14871                         + targetUserId + "\n " + Debug.getCallers(3));
14872             }
14873         }
14874         return targetUserId;
14875     }
14876
14877     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14878             String className, int flags) {
14879         boolean result = false;
14880         // For apps that don't have pre-defined UIDs, check for permission
14881         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14882             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14883                 if (ActivityManager.checkUidPermission(
14884                         INTERACT_ACROSS_USERS,
14885                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14886                     ComponentName comp = new ComponentName(aInfo.packageName, className);
14887                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
14888                             + " requests FLAG_SINGLE_USER, but app does not hold "
14889                             + INTERACT_ACROSS_USERS;
14890                     Slog.w(TAG, msg);
14891                     throw new SecurityException(msg);
14892                 }
14893                 // Permission passed
14894                 result = true;
14895             }
14896         } else if ("system".equals(componentProcessName)) {
14897             result = true;
14898         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14899             // Phone app and persistent apps are allowed to export singleuser providers.
14900             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14901                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14902         }
14903         if (DEBUG_MU) {
14904             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14905                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14906         }
14907         return result;
14908     }
14909
14910     /**
14911      * Checks to see if the caller is in the same app as the singleton
14912      * component, or the component is in a special app. It allows special apps
14913      * to export singleton components but prevents exporting singleton
14914      * components for regular apps.
14915      */
14916     boolean isValidSingletonCall(int callingUid, int componentUid) {
14917         int componentAppId = UserHandle.getAppId(componentUid);
14918         return UserHandle.isSameApp(callingUid, componentUid)
14919                 || componentAppId == Process.SYSTEM_UID
14920                 || componentAppId == Process.PHONE_UID
14921                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14922                         == PackageManager.PERMISSION_GRANTED;
14923     }
14924
14925     public int bindService(IApplicationThread caller, IBinder token,
14926             Intent service, String resolvedType,
14927             IServiceConnection connection, int flags, int userId) {
14928         enforceNotIsolatedCaller("bindService");
14929
14930         // Refuse possible leaked file descriptors
14931         if (service != null && service.hasFileDescriptors() == true) {
14932             throw new IllegalArgumentException("File descriptors passed in Intent");
14933         }
14934
14935         synchronized(this) {
14936             return mServices.bindServiceLocked(caller, token, service, resolvedType,
14937                     connection, flags, userId);
14938         }
14939     }
14940
14941     public boolean unbindService(IServiceConnection connection) {
14942         synchronized (this) {
14943             return mServices.unbindServiceLocked(connection);
14944         }
14945     }
14946
14947     public void publishService(IBinder token, Intent intent, IBinder service) {
14948         // Refuse possible leaked file descriptors
14949         if (intent != null && intent.hasFileDescriptors() == true) {
14950             throw new IllegalArgumentException("File descriptors passed in Intent");
14951         }
14952
14953         synchronized(this) {
14954             if (!(token instanceof ServiceRecord)) {
14955                 throw new IllegalArgumentException("Invalid service token");
14956             }
14957             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14958         }
14959     }
14960
14961     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14962         // Refuse possible leaked file descriptors
14963         if (intent != null && intent.hasFileDescriptors() == true) {
14964             throw new IllegalArgumentException("File descriptors passed in Intent");
14965         }
14966
14967         synchronized(this) {
14968             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14969         }
14970     }
14971
14972     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14973         synchronized(this) {
14974             if (!(token instanceof ServiceRecord)) {
14975                 throw new IllegalArgumentException("Invalid service token");
14976             }
14977             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14978         }
14979     }
14980     
14981     // =========================================================
14982     // BACKUP AND RESTORE
14983     // =========================================================
14984     
14985     // Cause the target app to be launched if necessary and its backup agent
14986     // instantiated.  The backup agent will invoke backupAgentCreated() on the
14987     // activity manager to announce its creation.
14988     public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14989         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14990         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14991
14992         synchronized(this) {
14993             // !!! TODO: currently no check here that we're already bound
14994             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14995             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14996             synchronized (stats) {
14997                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14998             }
14999
15000             // Backup agent is now in use, its package can't be stopped.
15001             try {
15002                 AppGlobals.getPackageManager().setPackageStoppedState(
15003                         app.packageName, false, UserHandle.getUserId(app.uid));
15004             } catch (RemoteException e) {
15005             } catch (IllegalArgumentException e) {
15006                 Slog.w(TAG, "Failed trying to unstop package "
15007                         + app.packageName + ": " + e);
15008             }
15009
15010             BackupRecord r = new BackupRecord(ss, app, backupMode);
15011             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15012                     ? new ComponentName(app.packageName, app.backupAgentName)
15013                     : new ComponentName("android", "FullBackupAgent");
15014             // startProcessLocked() returns existing proc's record if it's already running
15015             ProcessRecord proc = startProcessLocked(app.processName, app,
15016                     false, 0, "backup", hostingName, false, false, false);
15017             if (proc == null) {
15018                 Slog.e(TAG, "Unable to start backup agent process " + r);
15019                 return false;
15020             }
15021
15022             r.app = proc;
15023             mBackupTarget = r;
15024             mBackupAppName = app.packageName;
15025
15026             // Try not to kill the process during backup
15027             updateOomAdjLocked(proc);
15028
15029             // If the process is already attached, schedule the creation of the backup agent now.
15030             // If it is not yet live, this will be done when it attaches to the framework.
15031             if (proc.thread != null) {
15032                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15033                 try {
15034                     proc.thread.scheduleCreateBackupAgent(app,
15035                             compatibilityInfoForPackageLocked(app), backupMode);
15036                 } catch (RemoteException e) {
15037                     // Will time out on the backup manager side
15038                 }
15039             } else {
15040                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15041             }
15042             // Invariants: at this point, the target app process exists and the application
15043             // is either already running or in the process of coming up.  mBackupTarget and
15044             // mBackupAppName describe the app, so that when it binds back to the AM we
15045             // know that it's scheduled for a backup-agent operation.
15046         }
15047         
15048         return true;
15049     }
15050
15051     @Override
15052     public void clearPendingBackup() {
15053         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15054         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15055
15056         synchronized (this) {
15057             mBackupTarget = null;
15058             mBackupAppName = null;
15059         }
15060     }
15061
15062     // A backup agent has just come up
15063     public void backupAgentCreated(String agentPackageName, IBinder agent) {
15064         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15065                 + " = " + agent);
15066
15067         synchronized(this) {
15068             if (!agentPackageName.equals(mBackupAppName)) {
15069                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15070                 return;
15071             }
15072         }
15073
15074         long oldIdent = Binder.clearCallingIdentity();
15075         try {
15076             IBackupManager bm = IBackupManager.Stub.asInterface(
15077                     ServiceManager.getService(Context.BACKUP_SERVICE));
15078             bm.agentConnected(agentPackageName, agent);
15079         } catch (RemoteException e) {
15080             // can't happen; the backup manager service is local
15081         } catch (Exception e) {
15082             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15083             e.printStackTrace();
15084         } finally {
15085             Binder.restoreCallingIdentity(oldIdent);
15086         }
15087     }
15088
15089     // done with this agent
15090     public void unbindBackupAgent(ApplicationInfo appInfo) {
15091         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15092         if (appInfo == null) {
15093             Slog.w(TAG, "unbind backup agent for null app");
15094             return;
15095         }
15096
15097         synchronized(this) {
15098             try {
15099                 if (mBackupAppName == null) {
15100                     Slog.w(TAG, "Unbinding backup agent with no active backup");
15101                     return;
15102                 }
15103
15104                 if (!mBackupAppName.equals(appInfo.packageName)) {
15105                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15106                     return;
15107                 }
15108
15109                 // Not backing this app up any more; reset its OOM adjustment
15110                 final ProcessRecord proc = mBackupTarget.app;
15111                 updateOomAdjLocked(proc);
15112
15113                 // If the app crashed during backup, 'thread' will be null here
15114                 if (proc.thread != null) {
15115                     try {
15116                         proc.thread.scheduleDestroyBackupAgent(appInfo,
15117                                 compatibilityInfoForPackageLocked(appInfo));
15118                     } catch (Exception e) {
15119                         Slog.e(TAG, "Exception when unbinding backup agent:");
15120                         e.printStackTrace();
15121                     }
15122                 }
15123             } finally {
15124                 mBackupTarget = null;
15125                 mBackupAppName = null;
15126             }
15127         }
15128     }
15129     // =========================================================
15130     // BROADCASTS
15131     // =========================================================
15132
15133     private final List getStickiesLocked(String action, IntentFilter filter,
15134             List cur, int userId) {
15135         final ContentResolver resolver = mContext.getContentResolver();
15136         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15137         if (stickies == null) {
15138             return cur;
15139         }
15140         final ArrayList<Intent> list = stickies.get(action);
15141         if (list == null) {
15142             return cur;
15143         }
15144         int N = list.size();
15145         for (int i=0; i<N; i++) {
15146             Intent intent = list.get(i);
15147             if (filter.match(resolver, intent, true, TAG) >= 0) {
15148                 if (cur == null) {
15149                     cur = new ArrayList<Intent>();
15150                 }
15151                 cur.add(intent);
15152             }
15153         }
15154         return cur;
15155     }
15156
15157     boolean isPendingBroadcastProcessLocked(int pid) {
15158         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15159                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15160     }
15161
15162     void skipPendingBroadcastLocked(int pid) {
15163             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15164             for (BroadcastQueue queue : mBroadcastQueues) {
15165                 queue.skipPendingBroadcastLocked(pid);
15166             }
15167     }
15168
15169     // The app just attached; send any pending broadcasts that it should receive
15170     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15171         boolean didSomething = false;
15172         for (BroadcastQueue queue : mBroadcastQueues) {
15173             didSomething |= queue.sendPendingBroadcastsLocked(app);
15174         }
15175         return didSomething;
15176     }
15177
15178     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15179             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15180         enforceNotIsolatedCaller("registerReceiver");
15181         int callingUid;
15182         int callingPid;
15183         synchronized(this) {
15184             ProcessRecord callerApp = null;
15185             if (caller != null) {
15186                 callerApp = getRecordForAppLocked(caller);
15187                 if (callerApp == null) {
15188                     throw new SecurityException(
15189                             "Unable to find app for caller " + caller
15190                             + " (pid=" + Binder.getCallingPid()
15191                             + ") when registering receiver " + receiver);
15192                 }
15193                 if (callerApp.info.uid != Process.SYSTEM_UID &&
15194                         !callerApp.pkgList.containsKey(callerPackage) &&
15195                         !"android".equals(callerPackage)) {
15196                     throw new SecurityException("Given caller package " + callerPackage
15197                             + " is not running in process " + callerApp);
15198                 }
15199                 callingUid = callerApp.info.uid;
15200                 callingPid = callerApp.pid;
15201             } else {
15202                 callerPackage = null;
15203                 callingUid = Binder.getCallingUid();
15204                 callingPid = Binder.getCallingPid();
15205             }
15206
15207             userId = this.handleIncomingUser(callingPid, callingUid, userId,
15208                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15209
15210             List allSticky = null;
15211
15212             // Look for any matching sticky broadcasts...
15213             Iterator actions = filter.actionsIterator();
15214             if (actions != null) {
15215                 while (actions.hasNext()) {
15216                     String action = (String)actions.next();
15217                     allSticky = getStickiesLocked(action, filter, allSticky,
15218                             UserHandle.USER_ALL);
15219                     allSticky = getStickiesLocked(action, filter, allSticky,
15220                             UserHandle.getUserId(callingUid));
15221                 }
15222             } else {
15223                 allSticky = getStickiesLocked(null, filter, allSticky,
15224                         UserHandle.USER_ALL);
15225                 allSticky = getStickiesLocked(null, filter, allSticky,
15226                         UserHandle.getUserId(callingUid));
15227             }
15228
15229             // The first sticky in the list is returned directly back to
15230             // the client.
15231             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15232
15233             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15234                     + ": " + sticky);
15235
15236             if (receiver == null) {
15237                 return sticky;
15238             }
15239
15240             ReceiverList rl
15241                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15242             if (rl == null) {
15243                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15244                         userId, receiver);
15245                 if (rl.app != null) {
15246                     rl.app.receivers.add(rl);
15247                 } else {
15248                     try {
15249                         receiver.asBinder().linkToDeath(rl, 0);
15250                     } catch (RemoteException e) {
15251                         return sticky;
15252                     }
15253                     rl.linkedToDeath = true;
15254                 }
15255                 mRegisteredReceivers.put(receiver.asBinder(), rl);
15256             } else if (rl.uid != callingUid) {
15257                 throw new IllegalArgumentException(
15258                         "Receiver requested to register for uid " + callingUid
15259                         + " was previously registered for uid " + rl.uid);
15260             } else if (rl.pid != callingPid) {
15261                 throw new IllegalArgumentException(
15262                         "Receiver requested to register for pid " + callingPid
15263                         + " was previously registered for pid " + rl.pid);
15264             } else if (rl.userId != userId) {
15265                 throw new IllegalArgumentException(
15266                         "Receiver requested to register for user " + userId
15267                         + " was previously registered for user " + rl.userId);
15268             }
15269             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15270                     permission, callingUid, userId);
15271             rl.add(bf);
15272             if (!bf.debugCheck()) {
15273                 Slog.w(TAG, "==> For Dynamic broadast");
15274             }
15275             mReceiverResolver.addFilter(bf);
15276
15277             // Enqueue broadcasts for all existing stickies that match
15278             // this filter.
15279             if (allSticky != null) {
15280                 ArrayList receivers = new ArrayList();
15281                 receivers.add(bf);
15282
15283                 int N = allSticky.size();
15284                 for (int i=0; i<N; i++) {
15285                     Intent intent = (Intent)allSticky.get(i);
15286                     BroadcastQueue queue = broadcastQueueForIntent(intent);
15287                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15288                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15289                             null, null, false, true, true, -1);
15290                     queue.enqueueParallelBroadcastLocked(r);
15291                     queue.scheduleBroadcastsLocked();
15292                 }
15293             }
15294
15295             return sticky;
15296         }
15297     }
15298
15299     public void unregisterReceiver(IIntentReceiver receiver) {
15300         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15301
15302         final long origId = Binder.clearCallingIdentity();
15303         try {
15304             boolean doTrim = false;
15305
15306             synchronized(this) {
15307                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15308                 if (rl != null) {
15309                     if (rl.curBroadcast != null) {
15310                         BroadcastRecord r = rl.curBroadcast;
15311                         final boolean doNext = finishReceiverLocked(
15312                                 receiver.asBinder(), r.resultCode, r.resultData,
15313                                 r.resultExtras, r.resultAbort);
15314                         if (doNext) {
15315                             doTrim = true;
15316                             r.queue.processNextBroadcast(false);
15317                         }
15318                     }
15319
15320                     if (rl.app != null) {
15321                         rl.app.receivers.remove(rl);
15322                     }
15323                     removeReceiverLocked(rl);
15324                     if (rl.linkedToDeath) {
15325                         rl.linkedToDeath = false;
15326                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
15327                     }
15328                 }
15329             }
15330
15331             // If we actually concluded any broadcasts, we might now be able
15332             // to trim the recipients' apps from our working set
15333             if (doTrim) {
15334                 trimApplications();
15335                 return;
15336             }
15337
15338         } finally {
15339             Binder.restoreCallingIdentity(origId);
15340         }
15341     }
15342
15343     void removeReceiverLocked(ReceiverList rl) {
15344         mRegisteredReceivers.remove(rl.receiver.asBinder());
15345         int N = rl.size();
15346         for (int i=0; i<N; i++) {
15347             mReceiverResolver.removeFilter(rl.get(i));
15348         }
15349     }
15350     
15351     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15352         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15353             ProcessRecord r = mLruProcesses.get(i);
15354             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15355                 try {
15356                     r.thread.dispatchPackageBroadcast(cmd, packages);
15357                 } catch (RemoteException ex) {
15358                 }
15359             }
15360         }
15361     }
15362
15363     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15364             int callingUid, int[] users) {
15365         List<ResolveInfo> receivers = null;
15366         try {
15367             HashSet<ComponentName> singleUserReceivers = null;
15368             boolean scannedFirstReceivers = false;
15369             for (int user : users) {
15370                 // Skip users that have Shell restrictions
15371                 if (callingUid == Process.SHELL_UID
15372                         && getUserManagerLocked().hasUserRestriction(
15373                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15374                     continue;
15375                 }
15376                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15377                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15378                 if (user != 0 && newReceivers != null) {
15379                     // If this is not the primary user, we need to check for
15380                     // any receivers that should be filtered out.
15381                     for (int i=0; i<newReceivers.size(); i++) {
15382                         ResolveInfo ri = newReceivers.get(i);
15383                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15384                             newReceivers.remove(i);
15385                             i--;
15386                         }
15387                     }
15388                 }
15389                 if (newReceivers != null && newReceivers.size() == 0) {
15390                     newReceivers = null;
15391                 }
15392                 if (receivers == null) {
15393                     receivers = newReceivers;
15394                 } else if (newReceivers != null) {
15395                     // We need to concatenate the additional receivers
15396                     // found with what we have do far.  This would be easy,
15397                     // but we also need to de-dup any receivers that are
15398                     // singleUser.
15399                     if (!scannedFirstReceivers) {
15400                         // Collect any single user receivers we had already retrieved.
15401                         scannedFirstReceivers = true;
15402                         for (int i=0; i<receivers.size(); i++) {
15403                             ResolveInfo ri = receivers.get(i);
15404                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15405                                 ComponentName cn = new ComponentName(
15406                                         ri.activityInfo.packageName, ri.activityInfo.name);
15407                                 if (singleUserReceivers == null) {
15408                                     singleUserReceivers = new HashSet<ComponentName>();
15409                                 }
15410                                 singleUserReceivers.add(cn);
15411                             }
15412                         }
15413                     }
15414                     // Add the new results to the existing results, tracking
15415                     // and de-dupping single user receivers.
15416                     for (int i=0; i<newReceivers.size(); i++) {
15417                         ResolveInfo ri = newReceivers.get(i);
15418                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15419                             ComponentName cn = new ComponentName(
15420                                     ri.activityInfo.packageName, ri.activityInfo.name);
15421                             if (singleUserReceivers == null) {
15422                                 singleUserReceivers = new HashSet<ComponentName>();
15423                             }
15424                             if (!singleUserReceivers.contains(cn)) {
15425                                 singleUserReceivers.add(cn);
15426                                 receivers.add(ri);
15427                             }
15428                         } else {
15429                             receivers.add(ri);
15430                         }
15431                     }
15432                 }
15433             }
15434         } catch (RemoteException ex) {
15435             // pm is in same process, this will never happen.
15436         }
15437         return receivers;
15438     }
15439
15440     private final int broadcastIntentLocked(ProcessRecord callerApp,
15441             String callerPackage, Intent intent, String resolvedType,
15442             IIntentReceiver resultTo, int resultCode, String resultData,
15443             Bundle map, String requiredPermission, int appOp,
15444             boolean ordered, boolean sticky, int callingPid, int callingUid,
15445             int userId) {
15446         intent = new Intent(intent);
15447
15448         // By default broadcasts do not go to stopped apps.
15449         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15450
15451         if (DEBUG_BROADCAST_LIGHT) Slog.v(
15452             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15453             + " ordered=" + ordered + " userid=" + userId);
15454         if ((resultTo != null) && !ordered) {
15455             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15456         }
15457
15458         userId = handleIncomingUser(callingPid, callingUid, userId,
15459                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15460
15461         // Make sure that the user who is receiving this broadcast is started.
15462         // If not, we will just skip it.
15463
15464         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15465             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15466                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15467                 Slog.w(TAG, "Skipping broadcast of " + intent
15468                         + ": user " + userId + " is stopped");
15469                 return ActivityManager.BROADCAST_SUCCESS;
15470             }
15471         }
15472
15473         /*
15474          * Prevent non-system code (defined here to be non-persistent
15475          * processes) from sending protected broadcasts.
15476          */
15477         int callingAppId = UserHandle.getAppId(callingUid);
15478         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15479             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15480             || callingAppId == Process.NFC_UID || callingUid == 0) {
15481             // Always okay.
15482         } else if (callerApp == null || !callerApp.persistent) {
15483             try {
15484                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15485                         intent.getAction())) {
15486                     String msg = "Permission Denial: not allowed to send broadcast "
15487                             + intent.getAction() + " from pid="
15488                             + callingPid + ", uid=" + callingUid;
15489                     Slog.w(TAG, msg);
15490                     throw new SecurityException(msg);
15491                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15492                     // Special case for compatibility: we don't want apps to send this,
15493                     // but historically it has not been protected and apps may be using it
15494                     // to poke their own app widget.  So, instead of making it protected,
15495                     // just limit it to the caller.
15496                     if (callerApp == null) {
15497                         String msg = "Permission Denial: not allowed to send broadcast "
15498                                 + intent.getAction() + " from unknown caller.";
15499                         Slog.w(TAG, msg);
15500                         throw new SecurityException(msg);
15501                     } else if (intent.getComponent() != null) {
15502                         // They are good enough to send to an explicit component...  verify
15503                         // it is being sent to the calling app.
15504                         if (!intent.getComponent().getPackageName().equals(
15505                                 callerApp.info.packageName)) {
15506                             String msg = "Permission Denial: not allowed to send broadcast "
15507                                     + intent.getAction() + " to "
15508                                     + intent.getComponent().getPackageName() + " from "
15509                                     + callerApp.info.packageName;
15510                             Slog.w(TAG, msg);
15511                             throw new SecurityException(msg);
15512                         }
15513                     } else {
15514                         // Limit broadcast to their own package.
15515                         intent.setPackage(callerApp.info.packageName);
15516                     }
15517                 }
15518             } catch (RemoteException e) {
15519                 Slog.w(TAG, "Remote exception", e);
15520                 return ActivityManager.BROADCAST_SUCCESS;
15521             }
15522         }
15523
15524         // Handle special intents: if this broadcast is from the package
15525         // manager about a package being removed, we need to remove all of
15526         // its activities from the history stack.
15527         final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15528                 intent.getAction());
15529         if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15530                 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15531                 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15532                 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15533                 || uidRemoved) {
15534             if (checkComponentPermission(
15535                     android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15536                     callingPid, callingUid, -1, true)
15537                     == PackageManager.PERMISSION_GRANTED) {
15538                 if (uidRemoved) {
15539                     final Bundle intentExtras = intent.getExtras();
15540                     final int uid = intentExtras != null
15541                             ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15542                     if (uid >= 0) {
15543                         BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15544                         synchronized (bs) {
15545                             bs.removeUidStatsLocked(uid);
15546                         }
15547                         mAppOpsService.uidRemoved(uid);
15548                     }
15549                 } else {
15550                     // If resources are unavailable just force stop all
15551                     // those packages and flush the attribute cache as well.
15552                     if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15553                         String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15554                         if (list != null && (list.length > 0)) {
15555                             for (String pkg : list) {
15556                                 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15557                                         "storage unmount");
15558                             }
15559                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
15560                             sendPackageBroadcastLocked(
15561                                     IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15562                         }
15563                     } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15564                             intent.getAction())) {
15565                         cleanupRecentTasksLocked(UserHandle.USER_ALL);
15566                     } else {
15567                         Uri data = intent.getData();
15568                         String ssp;
15569                         if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15570                             boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15571                                     intent.getAction());
15572                             boolean fullUninstall = removed &&
15573                                     !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15574                             if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15575                                 forceStopPackageLocked(ssp, UserHandle.getAppId(
15576                                         intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15577                                         false, fullUninstall, userId,
15578                                         removed ? "pkg removed" : "pkg changed");
15579                             }
15580                             if (removed) {
15581                                 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15582                                         new String[] {ssp}, userId);
15583                                 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15584                                     mAppOpsService.packageRemoved(
15585                                             intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15586
15587                                     // Remove all permissions granted from/to this package
15588                                     removeUriPermissionsForPackageLocked(ssp, userId, true);
15589                                 }
15590                             }
15591                         }
15592                     }
15593                 }
15594             } else {
15595                 String msg = "Permission Denial: " + intent.getAction()
15596                         + " broadcast from " + callerPackage + " (pid=" + callingPid
15597                         + ", uid=" + callingUid + ")"
15598                         + " requires "
15599                         + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15600                 Slog.w(TAG, msg);
15601                 throw new SecurityException(msg);
15602             }
15603
15604         // Special case for adding a package: by default turn on compatibility
15605         // mode.
15606         } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15607             Uri data = intent.getData();
15608             String ssp;
15609             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15610                 mCompatModePackages.handlePackageAddedLocked(ssp,
15611                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15612             }
15613         }
15614
15615         /*
15616          * If this is the time zone changed action, queue up a message that will reset the timezone
15617          * of all currently running processes. This message will get queued up before the broadcast
15618          * happens.
15619          */
15620         if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15621             mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15622         }
15623
15624         /*
15625          * If the user set the time, let all running processes know.
15626          */
15627         if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15628             final int is24Hour = intent.getBooleanExtra(
15629                     Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15630             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15631             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15632             synchronized (stats) {
15633                 stats.noteCurrentTimeChangedLocked();
15634             }
15635         }
15636
15637         if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15638             mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15639         }
15640
15641         if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15642             ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15643             mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15644         }
15645
15646         // Add to the sticky list if requested.
15647         if (sticky) {
15648             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15649                     callingPid, callingUid)
15650                     != PackageManager.PERMISSION_GRANTED) {
15651                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15652                         + callingPid + ", uid=" + callingUid
15653                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15654                 Slog.w(TAG, msg);
15655                 throw new SecurityException(msg);
15656             }
15657             if (requiredPermission != null) {
15658                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
15659                         + " and enforce permission " + requiredPermission);
15660                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15661             }
15662             if (intent.getComponent() != null) {
15663                 throw new SecurityException(
15664                         "Sticky broadcasts can't target a specific component");
15665             }
15666             // We use userId directly here, since the "all" target is maintained
15667             // as a separate set of sticky broadcasts.
15668             if (userId != UserHandle.USER_ALL) {
15669                 // But first, if this is not a broadcast to all users, then
15670                 // make sure it doesn't conflict with an existing broadcast to
15671                 // all users.
15672                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15673                         UserHandle.USER_ALL);
15674                 if (stickies != null) {
15675                     ArrayList<Intent> list = stickies.get(intent.getAction());
15676                     if (list != null) {
15677                         int N = list.size();
15678                         int i;
15679                         for (i=0; i<N; i++) {
15680                             if (intent.filterEquals(list.get(i))) {
15681                                 throw new IllegalArgumentException(
15682                                         "Sticky broadcast " + intent + " for user "
15683                                         + userId + " conflicts with existing global broadcast");
15684                             }
15685                         }
15686                     }
15687                 }
15688             }
15689             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15690             if (stickies == null) {
15691                 stickies = new ArrayMap<String, ArrayList<Intent>>();
15692                 mStickyBroadcasts.put(userId, stickies);
15693             }
15694             ArrayList<Intent> list = stickies.get(intent.getAction());
15695             if (list == null) {
15696                 list = new ArrayList<Intent>();
15697                 stickies.put(intent.getAction(), list);
15698             }
15699             int N = list.size();
15700             int i;
15701             for (i=0; i<N; i++) {
15702                 if (intent.filterEquals(list.get(i))) {
15703                     // This sticky already exists, replace it.
15704                     list.set(i, new Intent(intent));
15705                     break;
15706                 }
15707             }
15708             if (i >= N) {
15709                 list.add(new Intent(intent));
15710             }
15711         }
15712
15713         int[] users;
15714         if (userId == UserHandle.USER_ALL) {
15715             // Caller wants broadcast to go to all started users.
15716             users = mStartedUserArray;
15717         } else {
15718             // Caller wants broadcast to go to one specific user.
15719             users = new int[] {userId};
15720         }
15721
15722         // Figure out who all will receive this broadcast.
15723         List receivers = null;
15724         List<BroadcastFilter> registeredReceivers = null;
15725         // Need to resolve the intent to interested receivers...
15726         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15727                  == 0) {
15728             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15729         }
15730         if (intent.getComponent() == null) {
15731             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15732                 // Query one target user at a time, excluding shell-restricted users
15733                 UserManagerService ums = getUserManagerLocked();
15734                 for (int i = 0; i < users.length; i++) {
15735                     if (ums.hasUserRestriction(
15736                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15737                         continue;
15738                     }
15739                     List<BroadcastFilter> registeredReceiversForUser =
15740                             mReceiverResolver.queryIntent(intent,
15741                                     resolvedType, false, users[i]);
15742                     if (registeredReceivers == null) {
15743                         registeredReceivers = registeredReceiversForUser;
15744                     } else if (registeredReceiversForUser != null) {
15745                         registeredReceivers.addAll(registeredReceiversForUser);
15746                     }
15747                 }
15748             } else {
15749                 registeredReceivers = mReceiverResolver.queryIntent(intent,
15750                         resolvedType, false, userId);
15751             }
15752         }
15753
15754         final boolean replacePending =
15755                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15756         
15757         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15758                 + " replacePending=" + replacePending);
15759         
15760         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15761         if (!ordered && NR > 0) {
15762             // If we are not serializing this broadcast, then send the
15763             // registered receivers separately so they don't wait for the
15764             // components to be launched.
15765             final BroadcastQueue queue = broadcastQueueForIntent(intent);
15766             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15767                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15768                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15769                     ordered, sticky, false, userId);
15770             if (DEBUG_BROADCAST) Slog.v(
15771                     TAG, "Enqueueing parallel broadcast " + r);
15772             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15773             if (!replaced) {
15774                 queue.enqueueParallelBroadcastLocked(r);
15775                 queue.scheduleBroadcastsLocked();
15776             }
15777             registeredReceivers = null;
15778             NR = 0;
15779         }
15780
15781         // Merge into one list.
15782         int ir = 0;
15783         if (receivers != null) {
15784             // A special case for PACKAGE_ADDED: do not allow the package
15785             // being added to see this broadcast.  This prevents them from
15786             // using this as a back door to get run as soon as they are
15787             // installed.  Maybe in the future we want to have a special install
15788             // broadcast or such for apps, but we'd like to deliberately make
15789             // this decision.
15790             String skipPackages[] = null;
15791             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15792                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15793                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15794                 Uri data = intent.getData();
15795                 if (data != null) {
15796                     String pkgName = data.getSchemeSpecificPart();
15797                     if (pkgName != null) {
15798                         skipPackages = new String[] { pkgName };
15799                     }
15800                 }
15801             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15802                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15803             }
15804             if (skipPackages != null && (skipPackages.length > 0)) {
15805                 for (String skipPackage : skipPackages) {
15806                     if (skipPackage != null) {
15807                         int NT = receivers.size();
15808                         for (int it=0; it<NT; it++) {
15809                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
15810                             if (curt.activityInfo.packageName.equals(skipPackage)) {
15811                                 receivers.remove(it);
15812                                 it--;
15813                                 NT--;
15814                             }
15815                         }
15816                     }
15817                 }
15818             }
15819
15820             int NT = receivers != null ? receivers.size() : 0;
15821             int it = 0;
15822             ResolveInfo curt = null;
15823             BroadcastFilter curr = null;
15824             while (it < NT && ir < NR) {
15825                 if (curt == null) {
15826                     curt = (ResolveInfo)receivers.get(it);
15827                 }
15828                 if (curr == null) {
15829                     curr = registeredReceivers.get(ir);
15830                 }
15831                 if (curr.getPriority() >= curt.priority) {
15832                     // Insert this broadcast record into the final list.
15833                     receivers.add(it, curr);
15834                     ir++;
15835                     curr = null;
15836                     it++;
15837                     NT++;
15838                 } else {
15839                     // Skip to the next ResolveInfo in the final list.
15840                     it++;
15841                     curt = null;
15842                 }
15843             }
15844         }
15845         while (ir < NR) {
15846             if (receivers == null) {
15847                 receivers = new ArrayList();
15848             }
15849             receivers.add(registeredReceivers.get(ir));
15850             ir++;
15851         }
15852
15853         if ((receivers != null && receivers.size() > 0)
15854                 || resultTo != null) {
15855             BroadcastQueue queue = broadcastQueueForIntent(intent);
15856             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15857                     callerPackage, callingPid, callingUid, resolvedType,
15858                     requiredPermission, appOp, receivers, resultTo, resultCode,
15859                     resultData, map, ordered, sticky, false, userId);
15860             if (DEBUG_BROADCAST) Slog.v(
15861                     TAG, "Enqueueing ordered broadcast " + r
15862                     + ": prev had " + queue.mOrderedBroadcasts.size());
15863             if (DEBUG_BROADCAST) {
15864                 int seq = r.intent.getIntExtra("seq", -1);
15865                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15866             }
15867             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
15868             if (!replaced) {
15869                 queue.enqueueOrderedBroadcastLocked(r);
15870                 queue.scheduleBroadcastsLocked();
15871             }
15872         }
15873
15874         return ActivityManager.BROADCAST_SUCCESS;
15875     }
15876
15877     final Intent verifyBroadcastLocked(Intent intent) {
15878         // Refuse possible leaked file descriptors
15879         if (intent != null && intent.hasFileDescriptors() == true) {
15880             throw new IllegalArgumentException("File descriptors passed in Intent");
15881         }
15882
15883         int flags = intent.getFlags();
15884
15885         if (!mProcessesReady) {
15886             // if the caller really truly claims to know what they're doing, go
15887             // ahead and allow the broadcast without launching any receivers
15888             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15889                 intent = new Intent(intent);
15890                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15891             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15892                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15893                         + " before boot completion");
15894                 throw new IllegalStateException("Cannot broadcast before boot completed");
15895             }
15896         }
15897
15898         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15899             throw new IllegalArgumentException(
15900                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15901         }
15902
15903         return intent;
15904     }
15905
15906     public final int broadcastIntent(IApplicationThread caller,
15907             Intent intent, String resolvedType, IIntentReceiver resultTo,
15908             int resultCode, String resultData, Bundle map,
15909             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15910         enforceNotIsolatedCaller("broadcastIntent");
15911         synchronized(this) {
15912             intent = verifyBroadcastLocked(intent);
15913
15914             final ProcessRecord callerApp = getRecordForAppLocked(caller);
15915             final int callingPid = Binder.getCallingPid();
15916             final int callingUid = Binder.getCallingUid();
15917             final long origId = Binder.clearCallingIdentity();
15918             int res = broadcastIntentLocked(callerApp,
15919                     callerApp != null ? callerApp.info.packageName : null,
15920                     intent, resolvedType, resultTo,
15921                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15922                     callingPid, callingUid, userId);
15923             Binder.restoreCallingIdentity(origId);
15924             return res;
15925         }
15926     }
15927
15928     int broadcastIntentInPackage(String packageName, int uid,
15929             Intent intent, String resolvedType, IIntentReceiver resultTo,
15930             int resultCode, String resultData, Bundle map,
15931             String requiredPermission, boolean serialized, boolean sticky, int userId) {
15932         synchronized(this) {
15933             intent = verifyBroadcastLocked(intent);
15934
15935             final long origId = Binder.clearCallingIdentity();
15936             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15937                     resultTo, resultCode, resultData, map, requiredPermission,
15938                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15939             Binder.restoreCallingIdentity(origId);
15940             return res;
15941         }
15942     }
15943
15944     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15945         // Refuse possible leaked file descriptors
15946         if (intent != null && intent.hasFileDescriptors() == true) {
15947             throw new IllegalArgumentException("File descriptors passed in Intent");
15948         }
15949
15950         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15951                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15952
15953         synchronized(this) {
15954             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15955                     != PackageManager.PERMISSION_GRANTED) {
15956                 String msg = "Permission Denial: unbroadcastIntent() from pid="
15957                         + Binder.getCallingPid()
15958                         + ", uid=" + Binder.getCallingUid()
15959                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15960                 Slog.w(TAG, msg);
15961                 throw new SecurityException(msg);
15962             }
15963             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15964             if (stickies != null) {
15965                 ArrayList<Intent> list = stickies.get(intent.getAction());
15966                 if (list != null) {
15967                     int N = list.size();
15968                     int i;
15969                     for (i=0; i<N; i++) {
15970                         if (intent.filterEquals(list.get(i))) {
15971                             list.remove(i);
15972                             break;
15973                         }
15974                     }
15975                     if (list.size() <= 0) {
15976                         stickies.remove(intent.getAction());
15977                     }
15978                 }
15979                 if (stickies.size() <= 0) {
15980                     mStickyBroadcasts.remove(userId);
15981                 }
15982             }
15983         }
15984     }
15985
15986     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15987             String resultData, Bundle resultExtras, boolean resultAbort) {
15988         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15989         if (r == null) {
15990             Slog.w(TAG, "finishReceiver called but not found on queue");
15991             return false;
15992         }
15993
15994         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15995     }
15996
15997     void backgroundServicesFinishedLocked(int userId) {
15998         for (BroadcastQueue queue : mBroadcastQueues) {
15999             queue.backgroundServicesFinishedLocked(userId);
16000         }
16001     }
16002
16003     public void finishReceiver(IBinder who, int resultCode, String resultData,
16004             Bundle resultExtras, boolean resultAbort) {
16005         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16006
16007         // Refuse possible leaked file descriptors
16008         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16009             throw new IllegalArgumentException("File descriptors passed in Bundle");
16010         }
16011
16012         final long origId = Binder.clearCallingIdentity();
16013         try {
16014             boolean doNext = false;
16015             BroadcastRecord r;
16016
16017             synchronized(this) {
16018                 r = broadcastRecordForReceiverLocked(who);
16019                 if (r != null) {
16020                     doNext = r.queue.finishReceiverLocked(r, resultCode,
16021                         resultData, resultExtras, resultAbort, true);
16022                 }
16023             }
16024
16025             if (doNext) {
16026                 r.queue.processNextBroadcast(false);
16027             }
16028             trimApplications();
16029         } finally {
16030             Binder.restoreCallingIdentity(origId);
16031         }
16032     }
16033     
16034     // =========================================================
16035     // INSTRUMENTATION
16036     // =========================================================
16037
16038     public boolean startInstrumentation(ComponentName className,
16039             String profileFile, int flags, Bundle arguments,
16040             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16041             int userId, String abiOverride) {
16042         enforceNotIsolatedCaller("startInstrumentation");
16043         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16044                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16045         // Refuse possible leaked file descriptors
16046         if (arguments != null && arguments.hasFileDescriptors()) {
16047             throw new IllegalArgumentException("File descriptors passed in Bundle");
16048         }
16049
16050         synchronized(this) {
16051             InstrumentationInfo ii = null;
16052             ApplicationInfo ai = null;
16053             try {
16054                 ii = mContext.getPackageManager().getInstrumentationInfo(
16055                     className, STOCK_PM_FLAGS);
16056                 ai = AppGlobals.getPackageManager().getApplicationInfo(
16057                         ii.targetPackage, STOCK_PM_FLAGS, userId);
16058             } catch (PackageManager.NameNotFoundException e) {
16059             } catch (RemoteException e) {
16060             }
16061             if (ii == null) {
16062                 reportStartInstrumentationFailure(watcher, className,
16063                         "Unable to find instrumentation info for: " + className);
16064                 return false;
16065             }
16066             if (ai == null) {
16067                 reportStartInstrumentationFailure(watcher, className,
16068                         "Unable to find instrumentation target package: " + ii.targetPackage);
16069                 return false;
16070             }
16071
16072             int match = mContext.getPackageManager().checkSignatures(
16073                     ii.targetPackage, ii.packageName);
16074             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16075                 String msg = "Permission Denial: starting instrumentation "
16076                         + className + " from pid="
16077                         + Binder.getCallingPid()
16078                         + ", uid=" + Binder.getCallingPid()
16079                         + " not allowed because package " + ii.packageName
16080                         + " does not have a signature matching the target "
16081                         + ii.targetPackage;
16082                 reportStartInstrumentationFailure(watcher, className, msg);
16083                 throw new SecurityException(msg);
16084             }
16085
16086             final long origId = Binder.clearCallingIdentity();
16087             // Instrumentation can kill and relaunch even persistent processes
16088             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16089                     "start instr");
16090             ProcessRecord app = addAppLocked(ai, false, abiOverride);
16091             app.instrumentationClass = className;
16092             app.instrumentationInfo = ai;
16093             app.instrumentationProfileFile = profileFile;
16094             app.instrumentationArguments = arguments;
16095             app.instrumentationWatcher = watcher;
16096             app.instrumentationUiAutomationConnection = uiAutomationConnection;
16097             app.instrumentationResultClass = className;
16098             Binder.restoreCallingIdentity(origId);
16099         }
16100
16101         return true;
16102     }
16103     
16104     /**
16105      * Report errors that occur while attempting to start Instrumentation.  Always writes the 
16106      * error to the logs, but if somebody is watching, send the report there too.  This enables
16107      * the "am" command to report errors with more information.
16108      * 
16109      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16110      * @param cn The component name of the instrumentation.
16111      * @param report The error report.
16112      */
16113     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 
16114             ComponentName cn, String report) {
16115         Slog.w(TAG, report);
16116         try {
16117             if (watcher != null) {
16118                 Bundle results = new Bundle();
16119                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16120                 results.putString("Error", report);
16121                 watcher.instrumentationStatus(cn, -1, results);
16122             }
16123         } catch (RemoteException e) {
16124             Slog.w(TAG, e);
16125         }
16126     }
16127
16128     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16129         if (app.instrumentationWatcher != null) {
16130             try {
16131                 // NOTE:  IInstrumentationWatcher *must* be oneway here
16132                 app.instrumentationWatcher.instrumentationFinished(
16133                     app.instrumentationClass,
16134                     resultCode,
16135                     results);
16136             } catch (RemoteException e) {
16137             }
16138         }
16139         if (app.instrumentationUiAutomationConnection != null) {
16140             try {
16141                 app.instrumentationUiAutomationConnection.shutdown();
16142             } catch (RemoteException re) {
16143                 /* ignore */
16144             }
16145             // Only a UiAutomation can set this flag and now that
16146             // it is finished we make sure it is reset to its default.
16147             mUserIsMonkey = false;
16148         }
16149         app.instrumentationWatcher = null;
16150         app.instrumentationUiAutomationConnection = null;
16151         app.instrumentationClass = null;
16152         app.instrumentationInfo = null;
16153         app.instrumentationProfileFile = null;
16154         app.instrumentationArguments = null;
16155
16156         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16157                 "finished inst");
16158     }
16159
16160     public void finishInstrumentation(IApplicationThread target,
16161             int resultCode, Bundle results) {
16162         int userId = UserHandle.getCallingUserId();
16163         // Refuse possible leaked file descriptors
16164         if (results != null && results.hasFileDescriptors()) {
16165             throw new IllegalArgumentException("File descriptors passed in Intent");
16166         }
16167
16168         synchronized(this) {
16169             ProcessRecord app = getRecordForAppLocked(target);
16170             if (app == null) {
16171                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16172                 return;
16173             }
16174             final long origId = Binder.clearCallingIdentity();
16175             finishInstrumentationLocked(app, resultCode, results);
16176             Binder.restoreCallingIdentity(origId);
16177         }
16178     }
16179
16180     // =========================================================
16181     // CONFIGURATION
16182     // =========================================================
16183     
16184     public ConfigurationInfo getDeviceConfigurationInfo() {
16185         ConfigurationInfo config = new ConfigurationInfo();
16186         synchronized (this) {
16187             config.reqTouchScreen = mConfiguration.touchscreen;
16188             config.reqKeyboardType = mConfiguration.keyboard;
16189             config.reqNavigation = mConfiguration.navigation;
16190             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16191                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16192                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16193             }
16194             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16195                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16196                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16197             }
16198             config.reqGlEsVersion = GL_ES_VERSION;
16199         }
16200         return config;
16201     }
16202
16203     ActivityStack getFocusedStack() {
16204         return mStackSupervisor.getFocusedStack();
16205     }
16206
16207     public Configuration getConfiguration() {
16208         Configuration ci;
16209         synchronized(this) {
16210             ci = new Configuration(mConfiguration);
16211         }
16212         return ci;
16213     }
16214
16215     public void updatePersistentConfiguration(Configuration values) {
16216         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16217                 "updateConfiguration()");
16218         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16219                 "updateConfiguration()");
16220         if (values == null) {
16221             throw new NullPointerException("Configuration must not be null");
16222         }
16223
16224         synchronized(this) {
16225             final long origId = Binder.clearCallingIdentity();
16226             updateConfigurationLocked(values, null, true, false);
16227             Binder.restoreCallingIdentity(origId);
16228         }
16229     }
16230
16231     public void updateConfiguration(Configuration values) {
16232         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16233                 "updateConfiguration()");
16234
16235         synchronized(this) {
16236             if (values == null && mWindowManager != null) {
16237                 // sentinel: fetch the current configuration from the window manager
16238                 values = mWindowManager.computeNewConfiguration();
16239             }
16240
16241             if (mWindowManager != null) {
16242                 mProcessList.applyDisplaySize(mWindowManager);
16243             }
16244
16245             final long origId = Binder.clearCallingIdentity();
16246             if (values != null) {
16247                 Settings.System.clearConfiguration(values);
16248             }
16249             updateConfigurationLocked(values, null, false, false);
16250             Binder.restoreCallingIdentity(origId);
16251         }
16252     }
16253
16254     /**
16255      * Do either or both things: (1) change the current configuration, and (2)
16256      * make sure the given activity is running with the (now) current
16257      * configuration.  Returns true if the activity has been left running, or
16258      * false if <var>starting</var> is being destroyed to match the new
16259      * configuration.
16260      * @param persistent TODO
16261      */
16262     boolean updateConfigurationLocked(Configuration values,
16263             ActivityRecord starting, boolean persistent, boolean initLocale) {
16264         int changes = 0;
16265
16266         if (values != null) {
16267             Configuration newConfig = new Configuration(mConfiguration);
16268             changes = newConfig.updateFrom(values);
16269             if (changes != 0) {
16270                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16271                     Slog.i(TAG, "Updating configuration to: " + values);
16272                 }
16273                 
16274                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16275
16276                 if (values.locale != null && !initLocale) {
16277                     saveLocaleLocked(values.locale, 
16278                                      !values.locale.equals(mConfiguration.locale),
16279                                      values.userSetLocale);
16280                 }
16281
16282                 mConfigurationSeq++;
16283                 if (mConfigurationSeq <= 0) {
16284                     mConfigurationSeq = 1;
16285                 }
16286                 newConfig.seq = mConfigurationSeq;
16287                 mConfiguration = newConfig;
16288                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16289                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16290                 //mUsageStatsService.noteStartConfig(newConfig);
16291
16292                 final Configuration configCopy = new Configuration(mConfiguration);
16293                 
16294                 // TODO: If our config changes, should we auto dismiss any currently
16295                 // showing dialogs?
16296                 mShowDialogs = shouldShowDialogs(newConfig);
16297
16298                 AttributeCache ac = AttributeCache.instance();
16299                 if (ac != null) {
16300                     ac.updateConfiguration(configCopy);
16301                 }
16302
16303                 // Make sure all resources in our process are updated
16304                 // right now, so that anyone who is going to retrieve
16305                 // resource values after we return will be sure to get
16306                 // the new ones.  This is especially important during
16307                 // boot, where the first config change needs to guarantee
16308                 // all resources have that config before following boot
16309                 // code is executed.
16310                 mSystemThread.applyConfigurationToResources(configCopy);
16311
16312                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16313                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16314                     msg.obj = new Configuration(configCopy);
16315                     mHandler.sendMessage(msg);
16316                 }
16317
16318                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16319                     ProcessRecord app = mLruProcesses.get(i);
16320                     try {
16321                         if (app.thread != null) {
16322                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16323                                     + app.processName + " new config " + mConfiguration);
16324                             app.thread.scheduleConfigurationChanged(configCopy);
16325                         }
16326                     } catch (Exception e) {
16327                     }
16328                 }
16329                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16330                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16331                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
16332                         | Intent.FLAG_RECEIVER_FOREGROUND);
16333                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16334                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
16335                         Process.SYSTEM_UID, UserHandle.USER_ALL);
16336                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16337                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16338                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16339                     broadcastIntentLocked(null, null, intent,
16340                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16341                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16342                 }
16343             }
16344         }
16345
16346         boolean kept = true;
16347         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16348         // mainStack is null during startup.
16349         if (mainStack != null) {
16350             if (changes != 0 && starting == null) {
16351                 // If the configuration changed, and the caller is not already
16352                 // in the process of starting an activity, then find the top
16353                 // activity to check if its configuration needs to change.
16354                 starting = mainStack.topRunningActivityLocked(null);
16355             }
16356
16357             if (starting != null) {
16358                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16359                 // And we need to make sure at this point that all other activities
16360                 // are made visible with the correct configuration.
16361                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16362             }
16363         }
16364
16365         if (values != null && mWindowManager != null) {
16366             mWindowManager.setNewConfiguration(mConfiguration);
16367         }
16368
16369         return kept;
16370     }
16371
16372     /**
16373      * Decide based on the configuration whether we should shouw the ANR,
16374      * crash, etc dialogs.  The idea is that if there is no affordnace to
16375      * press the on-screen buttons, we shouldn't show the dialog.
16376      *
16377      * A thought: SystemUI might also want to get told about this, the Power
16378      * dialog / global actions also might want different behaviors.
16379      */
16380     private static final boolean shouldShowDialogs(Configuration config) {
16381         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16382                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16383     }
16384
16385     /**
16386      * Save the locale.  You must be inside a synchronized (this) block.
16387      */
16388     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16389         if(isDiff) {
16390             SystemProperties.set("user.language", l.getLanguage());
16391             SystemProperties.set("user.region", l.getCountry());
16392         } 
16393
16394         if(isPersist) {
16395             SystemProperties.set("persist.sys.language", l.getLanguage());
16396             SystemProperties.set("persist.sys.country", l.getCountry());
16397             SystemProperties.set("persist.sys.localevar", l.getVariant());
16398
16399             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16400         }
16401     }
16402
16403     @Override
16404     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16405         synchronized (this) {
16406             ActivityRecord srec = ActivityRecord.forToken(token);
16407             if (srec.task != null && srec.task.stack != null) {
16408                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16409             }
16410         }
16411         return false;
16412     }
16413
16414     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16415             Intent resultData) {
16416
16417         synchronized (this) {
16418             final ActivityStack stack = ActivityRecord.getStackLocked(token);
16419             if (stack != null) {
16420                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16421             }
16422             return false;
16423         }
16424     }
16425
16426     public int getLaunchedFromUid(IBinder activityToken) {
16427         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16428         if (srec == null) {
16429             return -1;
16430         }
16431         return srec.launchedFromUid;
16432     }
16433
16434     public String getLaunchedFromPackage(IBinder activityToken) {
16435         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16436         if (srec == null) {
16437             return null;
16438         }
16439         return srec.launchedFromPackage;
16440     }
16441
16442     // =========================================================
16443     // LIFETIME MANAGEMENT
16444     // =========================================================
16445
16446     // Returns which broadcast queue the app is the current [or imminent] receiver
16447     // on, or 'null' if the app is not an active broadcast recipient.
16448     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16449         BroadcastRecord r = app.curReceiver;
16450         if (r != null) {
16451             return r.queue;
16452         }
16453
16454         // It's not the current receiver, but it might be starting up to become one
16455         synchronized (this) {
16456             for (BroadcastQueue queue : mBroadcastQueues) {
16457                 r = queue.mPendingBroadcast;
16458                 if (r != null && r.curApp == app) {
16459                     // found it; report which queue it's in
16460                     return queue;
16461                 }
16462             }
16463         }
16464
16465         return null;
16466     }
16467
16468     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16469             boolean doingAll, long now) {
16470         if (mAdjSeq == app.adjSeq) {
16471             // This adjustment has already been computed.
16472             return app.curRawAdj;
16473         }
16474
16475         if (app.thread == null) {
16476             app.adjSeq = mAdjSeq;
16477             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16478             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16479             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16480         }
16481
16482         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16483         app.adjSource = null;
16484         app.adjTarget = null;
16485         app.empty = false;
16486         app.cached = false;
16487
16488         final int activitiesSize = app.activities.size();
16489
16490         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16491             // The max adjustment doesn't allow this app to be anything
16492             // below foreground, so it is not worth doing work for it.
16493             app.adjType = "fixed";
16494             app.adjSeq = mAdjSeq;
16495             app.curRawAdj = app.maxAdj;
16496             app.foregroundActivities = false;
16497             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16498             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16499             // System processes can do UI, and when they do we want to have
16500             // them trim their memory after the user leaves the UI.  To
16501             // facilitate this, here we need to determine whether or not it
16502             // is currently showing UI.
16503             app.systemNoUi = true;
16504             if (app == TOP_APP) {
16505                 app.systemNoUi = false;
16506             } else if (activitiesSize > 0) {
16507                 for (int j = 0; j < activitiesSize; j++) {
16508                     final ActivityRecord r = app.activities.get(j);
16509                     if (r.visible) {
16510                         app.systemNoUi = false;
16511                     }
16512                 }
16513             }
16514             if (!app.systemNoUi) {
16515                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16516             }
16517             return (app.curAdj=app.maxAdj);
16518         }
16519
16520         app.systemNoUi = false;
16521
16522         // Determine the importance of the process, starting with most
16523         // important to least, and assign an appropriate OOM adjustment.
16524         int adj;
16525         int schedGroup;
16526         int procState;
16527         boolean foregroundActivities = false;
16528         BroadcastQueue queue;
16529         if (app == TOP_APP) {
16530             // The last app on the list is the foreground app.
16531             adj = ProcessList.FOREGROUND_APP_ADJ;
16532             schedGroup = Process.THREAD_GROUP_DEFAULT;
16533             app.adjType = "top-activity";
16534             foregroundActivities = true;
16535             procState = ActivityManager.PROCESS_STATE_TOP;
16536         } else if (app.instrumentationClass != null) {
16537             // Don't want to kill running instrumentation.
16538             adj = ProcessList.FOREGROUND_APP_ADJ;
16539             schedGroup = Process.THREAD_GROUP_DEFAULT;
16540             app.adjType = "instrumentation";
16541             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16542         } else if ((queue = isReceivingBroadcast(app)) != null) {
16543             // An app that is currently receiving a broadcast also
16544             // counts as being in the foreground for OOM killer purposes.
16545             // It's placed in a sched group based on the nature of the
16546             // broadcast as reflected by which queue it's active in.
16547             adj = ProcessList.FOREGROUND_APP_ADJ;
16548             schedGroup = (queue == mFgBroadcastQueue)
16549                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16550             app.adjType = "broadcast";
16551             procState = ActivityManager.PROCESS_STATE_RECEIVER;
16552         } else if (app.executingServices.size() > 0) {
16553             // An app that is currently executing a service callback also
16554             // counts as being in the foreground.
16555             adj = ProcessList.FOREGROUND_APP_ADJ;
16556             schedGroup = app.execServicesFg ?
16557                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16558             app.adjType = "exec-service";
16559             procState = ActivityManager.PROCESS_STATE_SERVICE;
16560             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16561         } else {
16562             // As far as we know the process is empty.  We may change our mind later.
16563             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16564             // At this point we don't actually know the adjustment.  Use the cached adj
16565             // value that the caller wants us to.
16566             adj = cachedAdj;
16567             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16568             app.cached = true;
16569             app.empty = true;
16570             app.adjType = "cch-empty";
16571         }
16572
16573         // Examine all activities if not already foreground.
16574         if (!foregroundActivities && activitiesSize > 0) {
16575             for (int j = 0; j < activitiesSize; j++) {
16576                 final ActivityRecord r = app.activities.get(j);
16577                 if (r.app != app) {
16578                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16579                             + app + "?!?");
16580                     continue;
16581                 }
16582                 if (r.visible) {
16583                     // App has a visible activity; only upgrade adjustment.
16584                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
16585                         adj = ProcessList.VISIBLE_APP_ADJ;
16586                         app.adjType = "visible";
16587                     }
16588                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
16589                         procState = ActivityManager.PROCESS_STATE_TOP;
16590                     }
16591                     schedGroup = Process.THREAD_GROUP_DEFAULT;
16592                     app.cached = false;
16593                     app.empty = false;
16594                     foregroundActivities = true;
16595                     break;
16596                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16597                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16598                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16599                         app.adjType = "pausing";
16600                     }
16601                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
16602                         procState = ActivityManager.PROCESS_STATE_TOP;
16603                     }
16604                     schedGroup = Process.THREAD_GROUP_DEFAULT;
16605                     app.cached = false;
16606                     app.empty = false;
16607                     foregroundActivities = true;
16608                 } else if (r.state == ActivityState.STOPPING) {
16609                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16610                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16611                         app.adjType = "stopping";
16612                     }
16613                     // For the process state, we will at this point consider the
16614                     // process to be cached.  It will be cached either as an activity
16615                     // or empty depending on whether the activity is finishing.  We do
16616                     // this so that we can treat the process as cached for purposes of
16617                     // memory trimming (determing current memory level, trim command to
16618                     // send to process) since there can be an arbitrary number of stopping
16619                     // processes and they should soon all go into the cached state.
16620                     if (!r.finishing) {
16621                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16622                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16623                         }
16624                     }
16625                     app.cached = false;
16626                     app.empty = false;
16627                     foregroundActivities = true;
16628                 } else {
16629                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16630                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16631                         app.adjType = "cch-act";
16632                     }
16633                 }
16634             }
16635         }
16636
16637         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16638             if (app.foregroundServices) {
16639                 // The user is aware of this app, so make it visible.
16640                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16641                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16642                 app.cached = false;
16643                 app.adjType = "fg-service";
16644                 schedGroup = Process.THREAD_GROUP_DEFAULT;
16645             } else if (app.forcingToForeground != null) {
16646                 // The user is aware of this app, so make it visible.
16647                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16648                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16649                 app.cached = false;
16650                 app.adjType = "force-fg";
16651                 app.adjSource = app.forcingToForeground;
16652                 schedGroup = Process.THREAD_GROUP_DEFAULT;
16653             }
16654         }
16655
16656         if (app == mHeavyWeightProcess) {
16657             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16658                 // We don't want to kill the current heavy-weight process.
16659                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16660                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16661                 app.cached = false;
16662                 app.adjType = "heavy";
16663             }
16664             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16665                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16666             }
16667         }
16668
16669         if (app == mHomeProcess) {
16670             if (adj > ProcessList.HOME_APP_ADJ) {
16671                 // This process is hosting what we currently consider to be the
16672                 // home app, so we don't want to let it go into the background.
16673                 adj = ProcessList.HOME_APP_ADJ;
16674                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16675                 app.cached = false;
16676                 app.adjType = "home";
16677             }
16678             if (procState > ActivityManager.PROCESS_STATE_HOME) {
16679                 procState = ActivityManager.PROCESS_STATE_HOME;
16680             }
16681         }
16682
16683         if (app == mPreviousProcess && app.activities.size() > 0) {
16684             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16685                 // This was the previous process that showed UI to the user.
16686                 // We want to try to keep it around more aggressively, to give
16687                 // a good experience around switching between two apps.
16688                 adj = ProcessList.PREVIOUS_APP_ADJ;
16689                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16690                 app.cached = false;
16691                 app.adjType = "previous";
16692             }
16693             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16694                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16695             }
16696         }
16697
16698         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16699                 + " reason=" + app.adjType);
16700
16701         // By default, we use the computed adjustment.  It may be changed if
16702         // there are applications dependent on our services or providers, but
16703         // this gives us a baseline and makes sure we don't get into an
16704         // infinite recursion.
16705         app.adjSeq = mAdjSeq;
16706         app.curRawAdj = adj;
16707         app.hasStartedServices = false;
16708
16709         if (mBackupTarget != null && app == mBackupTarget.app) {
16710             // If possible we want to avoid killing apps while they're being backed up
16711             if (adj > ProcessList.BACKUP_APP_ADJ) {
16712                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16713                 adj = ProcessList.BACKUP_APP_ADJ;
16714                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16715                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16716                 }
16717                 app.adjType = "backup";
16718                 app.cached = false;
16719             }
16720             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16721                 procState = ActivityManager.PROCESS_STATE_BACKUP;
16722             }
16723         }
16724
16725         boolean mayBeTop = false;
16726
16727         for (int is = app.services.size()-1;
16728                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16729                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16730                         || procState > ActivityManager.PROCESS_STATE_TOP);
16731                 is--) {
16732             ServiceRecord s = app.services.valueAt(is);
16733             if (s.startRequested) {
16734                 app.hasStartedServices = true;
16735                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16736                     procState = ActivityManager.PROCESS_STATE_SERVICE;
16737                 }
16738                 if (app.hasShownUi && app != mHomeProcess) {
16739                     // If this process has shown some UI, let it immediately
16740                     // go to the LRU list because it may be pretty heavy with
16741                     // UI stuff.  We'll tag it with a label just to help
16742                     // debug and understand what is going on.
16743                     if (adj > ProcessList.SERVICE_ADJ) {
16744                         app.adjType = "cch-started-ui-services";
16745                     }
16746                 } else {
16747                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16748                         // This service has seen some activity within
16749                         // recent memory, so we will keep its process ahead
16750                         // of the background processes.
16751                         if (adj > ProcessList.SERVICE_ADJ) {
16752                             adj = ProcessList.SERVICE_ADJ;
16753                             app.adjType = "started-services";
16754                             app.cached = false;
16755                         }
16756                     }
16757                     // If we have let the service slide into the background
16758                     // state, still have some text describing what it is doing
16759                     // even though the service no longer has an impact.
16760                     if (adj > ProcessList.SERVICE_ADJ) {
16761                         app.adjType = "cch-started-services";
16762                     }
16763                 }
16764             }
16765             for (int conni = s.connections.size()-1;
16766                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16767                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16768                             || procState > ActivityManager.PROCESS_STATE_TOP);
16769                     conni--) {
16770                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16771                 for (int i = 0;
16772                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16773                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16774                                 || procState > ActivityManager.PROCESS_STATE_TOP);
16775                         i++) {
16776                     // XXX should compute this based on the max of
16777                     // all connected clients.
16778                     ConnectionRecord cr = clist.get(i);
16779                     if (cr.binding.client == app) {
16780                         // Binding to ourself is not interesting.
16781                         continue;
16782                     }
16783                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16784                         ProcessRecord client = cr.binding.client;
16785                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
16786                                 TOP_APP, doingAll, now);
16787                         int clientProcState = client.curProcState;
16788                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16789                             // If the other app is cached for any reason, for purposes here
16790                             // we are going to consider it empty.  The specific cached state
16791                             // doesn't propagate except under certain conditions.
16792                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16793                         }
16794                         String adjType = null;
16795                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16796                             // Not doing bind OOM management, so treat
16797                             // this guy more like a started service.
16798                             if (app.hasShownUi && app != mHomeProcess) {
16799                                 // If this process has shown some UI, let it immediately
16800                                 // go to the LRU list because it may be pretty heavy with
16801                                 // UI stuff.  We'll tag it with a label just to help
16802                                 // debug and understand what is going on.
16803                                 if (adj > clientAdj) {
16804                                     adjType = "cch-bound-ui-services";
16805                                 }
16806                                 app.cached = false;
16807                                 clientAdj = adj;
16808                                 clientProcState = procState;
16809                             } else {
16810                                 if (now >= (s.lastActivity
16811                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16812                                     // This service has not seen activity within
16813                                     // recent memory, so allow it to drop to the
16814                                     // LRU list if there is no other reason to keep
16815                                     // it around.  We'll also tag it with a label just
16816                                     // to help debug and undertand what is going on.
16817                                     if (adj > clientAdj) {
16818                                         adjType = "cch-bound-services";
16819                                     }
16820                                     clientAdj = adj;
16821                                 }
16822                             }
16823                         }
16824                         if (adj > clientAdj) {
16825                             // If this process has recently shown UI, and
16826                             // the process that is binding to it is less
16827                             // important than being visible, then we don't
16828                             // care about the binding as much as we care
16829                             // about letting this process get into the LRU
16830                             // list to be killed and restarted if needed for
16831                             // memory.
16832                             if (app.hasShownUi && app != mHomeProcess
16833                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16834                                 adjType = "cch-bound-ui-services";
16835                             } else {
16836                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16837                                         |Context.BIND_IMPORTANT)) != 0) {
16838                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16839                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16840                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16841                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16842                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16843                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16844                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16845                                     adj = clientAdj;
16846                                 } else {
16847                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
16848                                         adj = ProcessList.VISIBLE_APP_ADJ;
16849                                     }
16850                                 }
16851                                 if (!client.cached) {
16852                                     app.cached = false;
16853                                 }
16854                                 adjType = "service";
16855                             }
16856                         }
16857                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16858                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16859                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
16860                             }
16861                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16862                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16863                                     // Special handling of clients who are in the top state.
16864                                     // We *may* want to consider this process to be in the
16865                                     // top state as well, but only if there is not another
16866                                     // reason for it to be running.  Being on the top is a
16867                                     // special state, meaning you are specifically running
16868                                     // for the current top app.  If the process is already
16869                                     // running in the background for some other reason, it
16870                                     // is more important to continue considering it to be
16871                                     // in the background state.
16872                                     mayBeTop = true;
16873                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16874                                 } else {
16875                                     // Special handling for above-top states (persistent
16876                                     // processes).  These should not bring the current process
16877                                     // into the top state, since they are not on top.  Instead
16878                                     // give them the best state after that.
16879                                     clientProcState =
16880                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16881                                 }
16882                             }
16883                         } else {
16884                             if (clientProcState <
16885                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16886                                 clientProcState =
16887                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16888                             }
16889                         }
16890                         if (procState > clientProcState) {
16891                             procState = clientProcState;
16892                         }
16893                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16894                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16895                             app.pendingUiClean = true;
16896                         }
16897                         if (adjType != null) {
16898                             app.adjType = adjType;
16899                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16900                                     .REASON_SERVICE_IN_USE;
16901                             app.adjSource = cr.binding.client;
16902                             app.adjSourceProcState = clientProcState;
16903                             app.adjTarget = s.name;
16904                         }
16905                     }
16906                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16907                         app.treatLikeActivity = true;
16908                     }
16909                     final ActivityRecord a = cr.activity;
16910                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16911                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16912                                 (a.visible || a.state == ActivityState.RESUMED
16913                                  || a.state == ActivityState.PAUSING)) {
16914                             adj = ProcessList.FOREGROUND_APP_ADJ;
16915                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16916                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
16917                             }
16918                             app.cached = false;
16919                             app.adjType = "service";
16920                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16921                                     .REASON_SERVICE_IN_USE;
16922                             app.adjSource = a;
16923                             app.adjSourceProcState = procState;
16924                             app.adjTarget = s.name;
16925                         }
16926                     }
16927                 }
16928             }
16929         }
16930
16931         for (int provi = app.pubProviders.size()-1;
16932                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16933                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16934                         || procState > ActivityManager.PROCESS_STATE_TOP);
16935                 provi--) {
16936             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16937             for (int i = cpr.connections.size()-1;
16938                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16939                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16940                             || procState > ActivityManager.PROCESS_STATE_TOP);
16941                     i--) {
16942                 ContentProviderConnection conn = cpr.connections.get(i);
16943                 ProcessRecord client = conn.client;
16944                 if (client == app) {
16945                     // Being our own client is not interesting.
16946                     continue;
16947                 }
16948                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16949                 int clientProcState = client.curProcState;
16950                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16951                     // If the other app is cached for any reason, for purposes here
16952                     // we are going to consider it empty.
16953                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16954                 }
16955                 if (adj > clientAdj) {
16956                     if (app.hasShownUi && app != mHomeProcess
16957                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16958                         app.adjType = "cch-ui-provider";
16959                     } else {
16960                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16961                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16962                         app.adjType = "provider";
16963                     }
16964                     app.cached &= client.cached;
16965                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16966                             .REASON_PROVIDER_IN_USE;
16967                     app.adjSource = client;
16968                     app.adjSourceProcState = clientProcState;
16969                     app.adjTarget = cpr.name;
16970                 }
16971                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16972                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16973                         // Special handling of clients who are in the top state.
16974                         // We *may* want to consider this process to be in the
16975                         // top state as well, but only if there is not another
16976                         // reason for it to be running.  Being on the top is a
16977                         // special state, meaning you are specifically running
16978                         // for the current top app.  If the process is already
16979                         // running in the background for some other reason, it
16980                         // is more important to continue considering it to be
16981                         // in the background state.
16982                         mayBeTop = true;
16983                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16984                     } else {
16985                         // Special handling for above-top states (persistent
16986                         // processes).  These should not bring the current process
16987                         // into the top state, since they are not on top.  Instead
16988                         // give them the best state after that.
16989                         clientProcState =
16990                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16991                     }
16992                 }
16993                 if (procState > clientProcState) {
16994                     procState = clientProcState;
16995                 }
16996                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16997                     schedGroup = Process.THREAD_GROUP_DEFAULT;
16998                 }
16999             }
17000             // If the provider has external (non-framework) process
17001             // dependencies, ensure that its adjustment is at least
17002             // FOREGROUND_APP_ADJ.
17003             if (cpr.hasExternalProcessHandles()) {
17004                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17005                     adj = ProcessList.FOREGROUND_APP_ADJ;
17006                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17007                     app.cached = false;
17008                     app.adjType = "provider";
17009                     app.adjTarget = cpr.name;
17010                 }
17011                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17012                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17013                 }
17014             }
17015         }
17016
17017         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17018             // A client of one of our services or providers is in the top state.  We
17019             // *may* want to be in the top state, but not if we are already running in
17020             // the background for some other reason.  For the decision here, we are going
17021             // to pick out a few specific states that we want to remain in when a client
17022             // is top (states that tend to be longer-term) and otherwise allow it to go
17023             // to the top state.
17024             switch (procState) {
17025                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17026                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17027                 case ActivityManager.PROCESS_STATE_SERVICE:
17028                     // These all are longer-term states, so pull them up to the top
17029                     // of the background states, but not all the way to the top state.
17030                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17031                     break;
17032                 default:
17033                     // Otherwise, top is a better choice, so take it.
17034                     procState = ActivityManager.PROCESS_STATE_TOP;
17035                     break;
17036             }
17037         }
17038
17039         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17040             if (app.hasClientActivities) {
17041                 // This is a cached process, but with client activities.  Mark it so.
17042                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17043                 app.adjType = "cch-client-act";
17044             } else if (app.treatLikeActivity) {
17045                 // This is a cached process, but somebody wants us to treat it like it has
17046                 // an activity, okay!
17047                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17048                 app.adjType = "cch-as-act";
17049             }
17050         }
17051
17052         if (adj == ProcessList.SERVICE_ADJ) {
17053             if (doingAll) {
17054                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17055                 mNewNumServiceProcs++;
17056                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17057                 if (!app.serviceb) {
17058                     // This service isn't far enough down on the LRU list to
17059                     // normally be a B service, but if we are low on RAM and it
17060                     // is large we want to force it down since we would prefer to
17061                     // keep launcher over it.
17062                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17063                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17064                         app.serviceHighRam = true;
17065                         app.serviceb = true;
17066                         //Slog.i(TAG, "ADJ " + app + " high ram!");
17067                     } else {
17068                         mNewNumAServiceProcs++;
17069                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
17070                     }
17071                 } else {
17072                     app.serviceHighRam = false;
17073                 }
17074             }
17075             if (app.serviceb) {
17076                 adj = ProcessList.SERVICE_B_ADJ;
17077             }
17078         }
17079
17080         app.curRawAdj = adj;
17081         
17082         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17083         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17084         if (adj > app.maxAdj) {
17085             adj = app.maxAdj;
17086             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17087                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17088             }
17089         }
17090
17091         // Do final modification to adj.  Everything we do between here and applying
17092         // the final setAdj must be done in this function, because we will also use
17093         // it when computing the final cached adj later.  Note that we don't need to
17094         // worry about this for max adj above, since max adj will always be used to
17095         // keep it out of the cached vaues.
17096         app.curAdj = app.modifyRawOomAdj(adj);
17097         app.curSchedGroup = schedGroup;
17098         app.curProcState = procState;
17099         app.foregroundActivities = foregroundActivities;
17100
17101         return app.curRawAdj;
17102     }
17103
17104     /**
17105      * Schedule PSS collection of a process.
17106      */
17107     void requestPssLocked(ProcessRecord proc, int procState) {
17108         if (mPendingPssProcesses.contains(proc)) {
17109             return;
17110         }
17111         if (mPendingPssProcesses.size() == 0) {
17112             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17113         }
17114         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17115         proc.pssProcState = procState;
17116         mPendingPssProcesses.add(proc);
17117     }
17118
17119     /**
17120      * Schedule PSS collection of all processes.
17121      */
17122     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17123         if (!always) {
17124             if (now < (mLastFullPssTime +
17125                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17126                 return;
17127             }
17128         }
17129         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17130         mLastFullPssTime = now;
17131         mFullPssPending = true;
17132         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17133         mPendingPssProcesses.clear();
17134         for (int i=mLruProcesses.size()-1; i>=0; i--) {
17135             ProcessRecord app = mLruProcesses.get(i);
17136             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17137                 app.pssProcState = app.setProcState;
17138                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17139                         isSleeping(), now);
17140                 mPendingPssProcesses.add(app);
17141             }
17142         }
17143         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17144     }
17145
17146     /**
17147      * Ask a given process to GC right now.
17148      */
17149     final void performAppGcLocked(ProcessRecord app) {
17150         try {
17151             app.lastRequestedGc = SystemClock.uptimeMillis();
17152             if (app.thread != null) {
17153                 if (app.reportLowMemory) {
17154                     app.reportLowMemory = false;
17155                     app.thread.scheduleLowMemory();
17156                 } else {
17157                     app.thread.processInBackground();
17158                 }
17159             }
17160         } catch (Exception e) {
17161             // whatever.
17162         }
17163     }
17164     
17165     /**
17166      * Returns true if things are idle enough to perform GCs.
17167      */
17168     private final boolean canGcNowLocked() {
17169         boolean processingBroadcasts = false;
17170         for (BroadcastQueue q : mBroadcastQueues) {
17171             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17172                 processingBroadcasts = true;
17173             }
17174         }
17175         return !processingBroadcasts
17176                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17177     }
17178     
17179     /**
17180      * Perform GCs on all processes that are waiting for it, but only
17181      * if things are idle.
17182      */
17183     final void performAppGcsLocked() {
17184         final int N = mProcessesToGc.size();
17185         if (N <= 0) {
17186             return;
17187         }
17188         if (canGcNowLocked()) {
17189             while (mProcessesToGc.size() > 0) {
17190                 ProcessRecord proc = mProcessesToGc.remove(0);
17191                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17192                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17193                             <= SystemClock.uptimeMillis()) {
17194                         // To avoid spamming the system, we will GC processes one
17195                         // at a time, waiting a few seconds between each.
17196                         performAppGcLocked(proc);
17197                         scheduleAppGcsLocked();
17198                         return;
17199                     } else {
17200                         // It hasn't been long enough since we last GCed this
17201                         // process...  put it in the list to wait for its time.
17202                         addProcessToGcListLocked(proc);
17203                         break;
17204                     }
17205                 }
17206             }
17207             
17208             scheduleAppGcsLocked();
17209         }
17210     }
17211     
17212     /**
17213      * If all looks good, perform GCs on all processes waiting for them.
17214      */
17215     final void performAppGcsIfAppropriateLocked() {
17216         if (canGcNowLocked()) {
17217             performAppGcsLocked();
17218             return;
17219         }
17220         // Still not idle, wait some more.
17221         scheduleAppGcsLocked();
17222     }
17223
17224     /**
17225      * Schedule the execution of all pending app GCs.
17226      */
17227     final void scheduleAppGcsLocked() {
17228         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17229         
17230         if (mProcessesToGc.size() > 0) {
17231             // Schedule a GC for the time to the next process.
17232             ProcessRecord proc = mProcessesToGc.get(0);
17233             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17234             
17235             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17236             long now = SystemClock.uptimeMillis();
17237             if (when < (now+GC_TIMEOUT)) {
17238                 when = now + GC_TIMEOUT;
17239             }
17240             mHandler.sendMessageAtTime(msg, when);
17241         }
17242     }
17243     
17244     /**
17245      * Add a process to the array of processes waiting to be GCed.  Keeps the
17246      * list in sorted order by the last GC time.  The process can't already be
17247      * on the list.
17248      */
17249     final void addProcessToGcListLocked(ProcessRecord proc) {
17250         boolean added = false;
17251         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17252             if (mProcessesToGc.get(i).lastRequestedGc <
17253                     proc.lastRequestedGc) {
17254                 added = true;
17255                 mProcessesToGc.add(i+1, proc);
17256                 break;
17257             }
17258         }
17259         if (!added) {
17260             mProcessesToGc.add(0, proc);
17261         }
17262     }
17263     
17264     /**
17265      * Set up to ask a process to GC itself.  This will either do it
17266      * immediately, or put it on the list of processes to gc the next
17267      * time things are idle.
17268      */
17269     final void scheduleAppGcLocked(ProcessRecord app) {
17270         long now = SystemClock.uptimeMillis();
17271         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17272             return;
17273         }
17274         if (!mProcessesToGc.contains(app)) {
17275             addProcessToGcListLocked(app);
17276             scheduleAppGcsLocked();
17277         }
17278     }
17279
17280     final void checkExcessivePowerUsageLocked(boolean doKills) {
17281         updateCpuStatsNow();
17282
17283         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17284         boolean doWakeKills = doKills;
17285         boolean doCpuKills = doKills;
17286         if (mLastPowerCheckRealtime == 0) {
17287             doWakeKills = false;
17288         }
17289         if (mLastPowerCheckUptime == 0) {
17290             doCpuKills = false;
17291         }
17292         if (stats.isScreenOn()) {
17293             doWakeKills = false;
17294         }
17295         final long curRealtime = SystemClock.elapsedRealtime();
17296         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17297         final long curUptime = SystemClock.uptimeMillis();
17298         final long uptimeSince = curUptime - mLastPowerCheckUptime;
17299         mLastPowerCheckRealtime = curRealtime;
17300         mLastPowerCheckUptime = curUptime;
17301         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17302             doWakeKills = false;
17303         }
17304         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17305             doCpuKills = false;
17306         }
17307         int i = mLruProcesses.size();
17308         while (i > 0) {
17309             i--;
17310             ProcessRecord app = mLruProcesses.get(i);
17311             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17312                 long wtime;
17313                 synchronized (stats) {
17314                     wtime = stats.getProcessWakeTime(app.info.uid,
17315                             app.pid, curRealtime);
17316                 }
17317                 long wtimeUsed = wtime - app.lastWakeTime;
17318                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17319                 if (DEBUG_POWER) {
17320                     StringBuilder sb = new StringBuilder(128);
17321                     sb.append("Wake for ");
17322                     app.toShortString(sb);
17323                     sb.append(": over ");
17324                     TimeUtils.formatDuration(realtimeSince, sb);
17325                     sb.append(" used ");
17326                     TimeUtils.formatDuration(wtimeUsed, sb);
17327                     sb.append(" (");
17328                     sb.append((wtimeUsed*100)/realtimeSince);
17329                     sb.append("%)");
17330                     Slog.i(TAG, sb.toString());
17331                     sb.setLength(0);
17332                     sb.append("CPU for ");
17333                     app.toShortString(sb);
17334                     sb.append(": over ");
17335                     TimeUtils.formatDuration(uptimeSince, sb);
17336                     sb.append(" used ");
17337                     TimeUtils.formatDuration(cputimeUsed, sb);
17338                     sb.append(" (");
17339                     sb.append((cputimeUsed*100)/uptimeSince);
17340                     sb.append("%)");
17341                     Slog.i(TAG, sb.toString());
17342                 }
17343                 // If a process has held a wake lock for more
17344                 // than 50% of the time during this period,
17345                 // that sounds bad.  Kill!
17346                 if (doWakeKills && realtimeSince > 0
17347                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
17348                     synchronized (stats) {
17349                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17350                                 realtimeSince, wtimeUsed);
17351                     }
17352                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17353                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17354                 } else if (doCpuKills && uptimeSince > 0
17355                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
17356                     synchronized (stats) {
17357                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17358                                 uptimeSince, cputimeUsed);
17359                     }
17360                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17361                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17362                 } else {
17363                     app.lastWakeTime = wtime;
17364                     app.lastCpuTime = app.curCpuTime;
17365                 }
17366             }
17367         }
17368     }
17369
17370     private final boolean applyOomAdjLocked(ProcessRecord app,
17371             ProcessRecord TOP_APP, boolean doingAll, long now) {
17372         boolean success = true;
17373
17374         if (app.curRawAdj != app.setRawAdj) {
17375             app.setRawAdj = app.curRawAdj;
17376         }
17377
17378         int changes = 0;
17379
17380         if (app.curAdj != app.setAdj) {
17381             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17382             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17383                 TAG, "Set " + app.pid + " " + app.processName +
17384                 " adj " + app.curAdj + ": " + app.adjType);
17385             app.setAdj = app.curAdj;
17386         }
17387
17388         if (app.setSchedGroup != app.curSchedGroup) {
17389             app.setSchedGroup = app.curSchedGroup;
17390             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17391                     "Setting process group of " + app.processName
17392                     + " to " + app.curSchedGroup);
17393             if (app.waitingToKill != null &&
17394                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17395                 app.kill(app.waitingToKill, true);
17396                 success = false;
17397             } else {
17398                 if (true) {
17399                     long oldId = Binder.clearCallingIdentity();
17400                     try {
17401                         Process.setProcessGroup(app.pid, app.curSchedGroup);
17402                     } catch (Exception e) {
17403                         Slog.w(TAG, "Failed setting process group of " + app.pid
17404                                 + " to " + app.curSchedGroup);
17405                         e.printStackTrace();
17406                     } finally {
17407                         Binder.restoreCallingIdentity(oldId);
17408                     }
17409                 } else {
17410                     if (app.thread != null) {
17411                         try {
17412                             app.thread.setSchedulingGroup(app.curSchedGroup);
17413                         } catch (RemoteException e) {
17414                         }
17415                     }
17416                 }
17417                 Process.setSwappiness(app.pid,
17418                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17419             }
17420         }
17421         if (app.repForegroundActivities != app.foregroundActivities) {
17422             app.repForegroundActivities = app.foregroundActivities;
17423             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17424         }
17425         if (app.repProcState != app.curProcState) {
17426             app.repProcState = app.curProcState;
17427             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17428             if (app.thread != null) {
17429                 try {
17430                     if (false) {
17431                         //RuntimeException h = new RuntimeException("here");
17432                         Slog.i(TAG, "Sending new process state " + app.repProcState
17433                                 + " to " + app /*, h*/);
17434                     }
17435                     app.thread.setProcessState(app.repProcState);
17436                 } catch (RemoteException e) {
17437                 }
17438             }
17439         }
17440         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17441                 app.setProcState)) {
17442             app.lastStateTime = now;
17443             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17444                     isSleeping(), now);
17445             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17446                     + ProcessList.makeProcStateString(app.setProcState) + " to "
17447                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17448                     + (app.nextPssTime-now) + ": " + app);
17449         } else {
17450             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17451                     && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17452                 requestPssLocked(app, app.setProcState);
17453                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17454                         isSleeping(), now);
17455             } else if (false && DEBUG_PSS) {
17456                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17457             }
17458         }
17459         if (app.setProcState != app.curProcState) {
17460             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17461                     "Proc state change of " + app.processName
17462                     + " to " + app.curProcState);
17463             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17464             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17465             if (setImportant && !curImportant) {
17466                 // This app is no longer something we consider important enough to allow to
17467                 // use arbitrary amounts of battery power.  Note
17468                 // its current wake lock time to later know to kill it if
17469                 // it is not behaving well.
17470                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17471                 synchronized (stats) {
17472                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17473                             app.pid, SystemClock.elapsedRealtime());
17474                 }
17475                 app.lastCpuTime = app.curCpuTime;
17476
17477             }
17478             app.setProcState = app.curProcState;
17479             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17480                 app.notCachedSinceIdle = false;
17481             }
17482             if (!doingAll) {
17483                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17484             } else {
17485                 app.procStateChanged = true;
17486             }
17487         }
17488
17489         if (changes != 0) {
17490             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17491             int i = mPendingProcessChanges.size()-1;
17492             ProcessChangeItem item = null;
17493             while (i >= 0) {
17494                 item = mPendingProcessChanges.get(i);
17495                 if (item.pid == app.pid) {
17496                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17497                     break;
17498                 }
17499                 i--;
17500             }
17501             if (i < 0) {
17502                 // No existing item in pending changes; need a new one.
17503                 final int NA = mAvailProcessChanges.size();
17504                 if (NA > 0) {
17505                     item = mAvailProcessChanges.remove(NA-1);
17506                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17507                 } else {
17508                     item = new ProcessChangeItem();
17509                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17510                 }
17511                 item.changes = 0;
17512                 item.pid = app.pid;
17513                 item.uid = app.info.uid;
17514                 if (mPendingProcessChanges.size() == 0) {
17515                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17516                             "*** Enqueueing dispatch processes changed!");
17517                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17518                 }
17519                 mPendingProcessChanges.add(item);
17520             }
17521             item.changes |= changes;
17522             item.processState = app.repProcState;
17523             item.foregroundActivities = app.repForegroundActivities;
17524             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17525                     + Integer.toHexString(System.identityHashCode(item))
17526                     + " " + app.toShortString() + ": changes=" + item.changes
17527                     + " procState=" + item.processState
17528                     + " foreground=" + item.foregroundActivities
17529                     + " type=" + app.adjType + " source=" + app.adjSource
17530                     + " target=" + app.adjTarget);
17531         }
17532
17533         return success;
17534     }
17535
17536     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17537         if (proc.thread != null) {
17538             if (proc.baseProcessTracker != null) {
17539                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17540             }
17541             if (proc.repProcState >= 0) {
17542                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17543                         proc.repProcState);
17544             }
17545         }
17546     }
17547
17548     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17549             ProcessRecord TOP_APP, boolean doingAll, long now) {
17550         if (app.thread == null) {
17551             return false;
17552         }
17553
17554         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17555
17556         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17557     }
17558
17559     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17560             boolean oomAdj) {
17561         if (isForeground != proc.foregroundServices) {
17562             proc.foregroundServices = isForeground;
17563             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17564                     proc.info.uid);
17565             if (isForeground) {
17566                 if (curProcs == null) {
17567                     curProcs = new ArrayList<ProcessRecord>();
17568                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17569                 }
17570                 if (!curProcs.contains(proc)) {
17571                     curProcs.add(proc);
17572                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17573                             proc.info.packageName, proc.info.uid);
17574                 }
17575             } else {
17576                 if (curProcs != null) {
17577                     if (curProcs.remove(proc)) {
17578                         mBatteryStatsService.noteEvent(
17579                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17580                                 proc.info.packageName, proc.info.uid);
17581                         if (curProcs.size() <= 0) {
17582                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17583                         }
17584                     }
17585                 }
17586             }
17587             if (oomAdj) {
17588                 updateOomAdjLocked();
17589             }
17590         }
17591     }
17592
17593     private final ActivityRecord resumedAppLocked() {
17594         ActivityRecord act = mStackSupervisor.resumedAppLocked();
17595         String pkg;
17596         int uid;
17597         if (act != null) {
17598             pkg = act.packageName;
17599             uid = act.info.applicationInfo.uid;
17600         } else {
17601             pkg = null;
17602             uid = -1;
17603         }
17604         // Has the UID or resumed package name changed?
17605         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17606                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17607             if (mCurResumedPackage != null) {
17608                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17609                         mCurResumedPackage, mCurResumedUid);
17610             }
17611             mCurResumedPackage = pkg;
17612             mCurResumedUid = uid;
17613             if (mCurResumedPackage != null) {
17614                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17615                         mCurResumedPackage, mCurResumedUid);
17616             }
17617         }
17618         return act;
17619     }
17620
17621     final boolean updateOomAdjLocked(ProcessRecord app) {
17622         final ActivityRecord TOP_ACT = resumedAppLocked();
17623         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17624         final boolean wasCached = app.cached;
17625
17626         mAdjSeq++;
17627
17628         // This is the desired cached adjusment we want to tell it to use.
17629         // If our app is currently cached, we know it, and that is it.  Otherwise,
17630         // we don't know it yet, and it needs to now be cached we will then
17631         // need to do a complete oom adj.
17632         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17633                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17634         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17635                 SystemClock.uptimeMillis());
17636         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17637             // Changed to/from cached state, so apps after it in the LRU
17638             // list may also be changed.
17639             updateOomAdjLocked();
17640         }
17641         return success;
17642     }
17643
17644     final void updateOomAdjLocked() {
17645         final ActivityRecord TOP_ACT = resumedAppLocked();
17646         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17647         final long now = SystemClock.uptimeMillis();
17648         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17649         final int N = mLruProcesses.size();
17650
17651         if (false) {
17652             RuntimeException e = new RuntimeException();
17653             e.fillInStackTrace();
17654             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17655         }
17656
17657         mAdjSeq++;
17658         mNewNumServiceProcs = 0;
17659         mNewNumAServiceProcs = 0;
17660
17661         final int emptyProcessLimit;
17662         final int cachedProcessLimit;
17663         if (mProcessLimit <= 0) {
17664             emptyProcessLimit = cachedProcessLimit = 0;
17665         } else if (mProcessLimit == 1) {
17666             emptyProcessLimit = 1;
17667             cachedProcessLimit = 0;
17668         } else {
17669             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17670             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17671         }
17672
17673         // Let's determine how many processes we have running vs.
17674         // how many slots we have for background processes; we may want
17675         // to put multiple processes in a slot of there are enough of
17676         // them.
17677         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17678                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17679         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17680         if (numEmptyProcs > cachedProcessLimit) {
17681             // If there are more empty processes than our limit on cached
17682             // processes, then use the cached process limit for the factor.
17683             // This ensures that the really old empty processes get pushed
17684             // down to the bottom, so if we are running low on memory we will
17685             // have a better chance at keeping around more cached processes
17686             // instead of a gazillion empty processes.
17687             numEmptyProcs = cachedProcessLimit;
17688         }
17689         int emptyFactor = numEmptyProcs/numSlots;
17690         if (emptyFactor < 1) emptyFactor = 1;
17691         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17692         if (cachedFactor < 1) cachedFactor = 1;
17693         int stepCached = 0;
17694         int stepEmpty = 0;
17695         int numCached = 0;
17696         int numEmpty = 0;
17697         int numTrimming = 0;
17698
17699         mNumNonCachedProcs = 0;
17700         mNumCachedHiddenProcs = 0;
17701
17702         // First update the OOM adjustment for each of the
17703         // application processes based on their current state.
17704         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17705         int nextCachedAdj = curCachedAdj+1;
17706         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17707         int nextEmptyAdj = curEmptyAdj+2;
17708         for (int i=N-1; i>=0; i--) {
17709             ProcessRecord app = mLruProcesses.get(i);
17710             if (!app.killedByAm && app.thread != null) {
17711                 app.procStateChanged = false;
17712                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17713
17714                 // If we haven't yet assigned the final cached adj
17715                 // to the process, do that now.
17716                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17717                     switch (app.curProcState) {
17718                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17719                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17720                             // This process is a cached process holding activities...
17721                             // assign it the next cached value for that type, and then
17722                             // step that cached level.
17723                             app.curRawAdj = curCachedAdj;
17724                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17725                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17726                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17727                                     + ")");
17728                             if (curCachedAdj != nextCachedAdj) {
17729                                 stepCached++;
17730                                 if (stepCached >= cachedFactor) {
17731                                     stepCached = 0;
17732                                     curCachedAdj = nextCachedAdj;
17733                                     nextCachedAdj += 2;
17734                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17735                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17736                                     }
17737                                 }
17738                             }
17739                             break;
17740                         default:
17741                             // For everything else, assign next empty cached process
17742                             // level and bump that up.  Note that this means that
17743                             // long-running services that have dropped down to the
17744                             // cached level will be treated as empty (since their process
17745                             // state is still as a service), which is what we want.
17746                             app.curRawAdj = curEmptyAdj;
17747                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17748                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17749                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17750                                     + ")");
17751                             if (curEmptyAdj != nextEmptyAdj) {
17752                                 stepEmpty++;
17753                                 if (stepEmpty >= emptyFactor) {
17754                                     stepEmpty = 0;
17755                                     curEmptyAdj = nextEmptyAdj;
17756                                     nextEmptyAdj += 2;
17757                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17758                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17759                                     }
17760                                 }
17761                             }
17762                             break;
17763                     }
17764                 }
17765
17766                 applyOomAdjLocked(app, TOP_APP, true, now);
17767
17768                 // Count the number of process types.
17769                 switch (app.curProcState) {
17770                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17771                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17772                         mNumCachedHiddenProcs++;
17773                         numCached++;
17774                         if (numCached > cachedProcessLimit) {
17775                             app.kill("cached #" + numCached, true);
17776                         }
17777                         break;
17778                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17779                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17780                                 && app.lastActivityTime < oldTime) {
17781                             app.kill("empty for "
17782                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17783                                     / 1000) + "s", true);
17784                         } else {
17785                             numEmpty++;
17786                             if (numEmpty > emptyProcessLimit) {
17787                                 app.kill("empty #" + numEmpty, true);
17788                             }
17789                         }
17790                         break;
17791                     default:
17792                         mNumNonCachedProcs++;
17793                         break;
17794                 }
17795
17796                 if (app.isolated && app.services.size() <= 0) {
17797                     // If this is an isolated process, and there are no
17798                     // services running in it, then the process is no longer
17799                     // needed.  We agressively kill these because we can by
17800                     // definition not re-use the same process again, and it is
17801                     // good to avoid having whatever code was running in them
17802                     // left sitting around after no longer needed.
17803                     app.kill("isolated not needed", true);
17804                 }
17805
17806                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17807                         && !app.killedByAm) {
17808                     numTrimming++;
17809                 }
17810             }
17811         }
17812
17813         mNumServiceProcs = mNewNumServiceProcs;
17814
17815         // Now determine the memory trimming level of background processes.
17816         // Unfortunately we need to start at the back of the list to do this
17817         // properly.  We only do this if the number of background apps we
17818         // are managing to keep around is less than half the maximum we desire;
17819         // if we are keeping a good number around, we'll let them use whatever
17820         // memory they want.
17821         final int numCachedAndEmpty = numCached + numEmpty;
17822         int memFactor;
17823         if (numCached <= ProcessList.TRIM_CACHED_APPS
17824                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17825             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17826                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17827             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17828                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17829             } else {
17830                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17831             }
17832         } else {
17833             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17834         }
17835         // We always allow the memory level to go up (better).  We only allow it to go
17836         // down if we are in a state where that is allowed, *and* the total number of processes
17837         // has gone down since last time.
17838         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17839                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17840                 + " last=" + mLastNumProcesses);
17841         if (memFactor > mLastMemoryLevel) {
17842             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17843                 memFactor = mLastMemoryLevel;
17844                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17845             }
17846         }
17847         mLastMemoryLevel = memFactor;
17848         mLastNumProcesses = mLruProcesses.size();
17849         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17850         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17851         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17852             if (mLowRamStartTime == 0) {
17853                 mLowRamStartTime = now;
17854             }
17855             int step = 0;
17856             int fgTrimLevel;
17857             switch (memFactor) {
17858                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17859                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17860                     break;
17861                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17862                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17863                     break;
17864                 default:
17865                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17866                     break;
17867             }
17868             int factor = numTrimming/3;
17869             int minFactor = 2;
17870             if (mHomeProcess != null) minFactor++;
17871             if (mPreviousProcess != null) minFactor++;
17872             if (factor < minFactor) factor = minFactor;
17873             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17874             for (int i=N-1; i>=0; i--) {
17875                 ProcessRecord app = mLruProcesses.get(i);
17876                 if (allChanged || app.procStateChanged) {
17877                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
17878                     app.procStateChanged = false;
17879                 }
17880                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17881                         && !app.killedByAm) {
17882                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
17883                         try {
17884                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17885                                     "Trimming memory of " + app.processName
17886                                     + " to " + curLevel);
17887                             app.thread.scheduleTrimMemory(curLevel);
17888                         } catch (RemoteException e) {
17889                         }
17890                         if (false) {
17891                             // For now we won't do this; our memory trimming seems
17892                             // to be good enough at this point that destroying
17893                             // activities causes more harm than good.
17894                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17895                                     && app != mHomeProcess && app != mPreviousProcess) {
17896                                 // Need to do this on its own message because the stack may not
17897                                 // be in a consistent state at this point.
17898                                 // For these apps we will also finish their activities
17899                                 // to help them free memory.
17900                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17901                             }
17902                         }
17903                     }
17904                     app.trimMemoryLevel = curLevel;
17905                     step++;
17906                     if (step >= factor) {
17907                         step = 0;
17908                         switch (curLevel) {
17909                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17910                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17911                                 break;
17912                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17913                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17914                                 break;
17915                         }
17916                     }
17917                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17918                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17919                             && app.thread != null) {
17920                         try {
17921                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17922                                     "Trimming memory of heavy-weight " + app.processName
17923                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17924                             app.thread.scheduleTrimMemory(
17925                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17926                         } catch (RemoteException e) {
17927                         }
17928                     }
17929                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17930                 } else {
17931                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17932                             || app.systemNoUi) && app.pendingUiClean) {
17933                         // If this application is now in the background and it
17934                         // had done UI, then give it the special trim level to
17935                         // have it free UI resources.
17936                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17937                         if (app.trimMemoryLevel < level && app.thread != null) {
17938                             try {
17939                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17940                                         "Trimming memory of bg-ui " + app.processName
17941                                         + " to " + level);
17942                                 app.thread.scheduleTrimMemory(level);
17943                             } catch (RemoteException e) {
17944                             }
17945                         }
17946                         app.pendingUiClean = false;
17947                     }
17948                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17949                         try {
17950                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17951                                     "Trimming memory of fg " + app.processName
17952                                     + " to " + fgTrimLevel);
17953                             app.thread.scheduleTrimMemory(fgTrimLevel);
17954                         } catch (RemoteException e) {
17955                         }
17956                     }
17957                     app.trimMemoryLevel = fgTrimLevel;
17958                 }
17959             }
17960         } else {
17961             if (mLowRamStartTime != 0) {
17962                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17963                 mLowRamStartTime = 0;
17964             }
17965             for (int i=N-1; i>=0; i--) {
17966                 ProcessRecord app = mLruProcesses.get(i);
17967                 if (allChanged || app.procStateChanged) {
17968                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
17969                     app.procStateChanged = false;
17970                 }
17971                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17972                         || app.systemNoUi) && app.pendingUiClean) {
17973                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17974                             && app.thread != null) {
17975                         try {
17976                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17977                                     "Trimming memory of ui hidden " + app.processName
17978                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17979                             app.thread.scheduleTrimMemory(
17980                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17981                         } catch (RemoteException e) {
17982                         }
17983                     }
17984                     app.pendingUiClean = false;
17985                 }
17986                 app.trimMemoryLevel = 0;
17987             }
17988         }
17989
17990         if (mAlwaysFinishActivities) {
17991             // Need to do this on its own message because the stack may not
17992             // be in a consistent state at this point.
17993             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17994         }
17995
17996         if (allChanged) {
17997             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17998         }
17999
18000         if (mProcessStats.shouldWriteNowLocked(now)) {
18001             mHandler.post(new Runnable() {
18002                 @Override public void run() {
18003                     synchronized (ActivityManagerService.this) {
18004                         mProcessStats.writeStateAsyncLocked();
18005                     }
18006                 }
18007             });
18008         }
18009
18010         if (DEBUG_OOM_ADJ) {
18011             if (false) {
18012                 RuntimeException here = new RuntimeException("here");
18013                 here.fillInStackTrace();
18014                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18015             } else {
18016                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18017             }
18018         }
18019     }
18020
18021     final void trimApplications() {
18022         synchronized (this) {
18023             int i;
18024
18025             // First remove any unused application processes whose package
18026             // has been removed.
18027             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18028                 final ProcessRecord app = mRemovedProcesses.get(i);
18029                 if (app.activities.size() == 0
18030                         && app.curReceiver == null && app.services.size() == 0) {
18031                     Slog.i(
18032                         TAG, "Exiting empty application process "
18033                         + app.processName + " ("
18034                         + (app.thread != null ? app.thread.asBinder() : null)
18035                         + ")\n");
18036                     if (app.pid > 0 && app.pid != MY_PID) {
18037                         app.kill("empty", false);
18038                     } else {
18039                         try {
18040                             app.thread.scheduleExit();
18041                         } catch (Exception e) {
18042                             // Ignore exceptions.
18043                         }
18044                     }
18045                     cleanUpApplicationRecordLocked(app, false, true, -1);
18046                     mRemovedProcesses.remove(i);
18047
18048                     if (app.persistent) {
18049                         addAppLocked(app.info, false, null /* ABI override */);
18050                     }
18051                 }
18052             }
18053
18054             // Now update the oom adj for all processes.
18055             updateOomAdjLocked();
18056         }
18057     }
18058
18059     /** This method sends the specified signal to each of the persistent apps */
18060     public void signalPersistentProcesses(int sig) throws RemoteException {
18061         if (sig != Process.SIGNAL_USR1) {
18062             throw new SecurityException("Only SIGNAL_USR1 is allowed");
18063         }
18064
18065         synchronized (this) {
18066             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18067                     != PackageManager.PERMISSION_GRANTED) {
18068                 throw new SecurityException("Requires permission "
18069                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18070             }
18071
18072             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18073                 ProcessRecord r = mLruProcesses.get(i);
18074                 if (r.thread != null && r.persistent) {
18075                     Process.sendSignal(r.pid, sig);
18076                 }
18077             }
18078         }
18079     }
18080
18081     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18082         if (proc == null || proc == mProfileProc) {
18083             proc = mProfileProc;
18084             profileType = mProfileType;
18085             clearProfilerLocked();
18086         }
18087         if (proc == null) {
18088             return;
18089         }
18090         try {
18091             proc.thread.profilerControl(false, null, profileType);
18092         } catch (RemoteException e) {
18093             throw new IllegalStateException("Process disappeared");
18094         }
18095     }
18096
18097     private void clearProfilerLocked() {
18098         if (mProfileFd != null) {
18099             try {
18100                 mProfileFd.close();
18101             } catch (IOException e) {
18102             }
18103         }
18104         mProfileApp = null;
18105         mProfileProc = null;
18106         mProfileFile = null;
18107         mProfileType = 0;
18108         mAutoStopProfiler = false;
18109         mSamplingInterval = 0;
18110     }
18111
18112     public boolean profileControl(String process, int userId, boolean start,
18113             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18114
18115         try {
18116             synchronized (this) {
18117                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18118                 // its own permission.
18119                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18120                         != PackageManager.PERMISSION_GRANTED) {
18121                     throw new SecurityException("Requires permission "
18122                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18123                 }
18124
18125                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18126                     throw new IllegalArgumentException("null profile info or fd");
18127                 }
18128
18129                 ProcessRecord proc = null;
18130                 if (process != null) {
18131                     proc = findProcessLocked(process, userId, "profileControl");
18132                 }
18133
18134                 if (start && (proc == null || proc.thread == null)) {
18135                     throw new IllegalArgumentException("Unknown process: " + process);
18136                 }
18137
18138                 if (start) {
18139                     stopProfilerLocked(null, 0);
18140                     setProfileApp(proc.info, proc.processName, profilerInfo);
18141                     mProfileProc = proc;
18142                     mProfileType = profileType;
18143                     ParcelFileDescriptor fd = profilerInfo.profileFd;
18144                     try {
18145                         fd = fd.dup();
18146                     } catch (IOException e) {
18147                         fd = null;
18148                     }
18149                     profilerInfo.profileFd = fd;
18150                     proc.thread.profilerControl(start, profilerInfo, profileType);
18151                     fd = null;
18152                     mProfileFd = null;
18153                 } else {
18154                     stopProfilerLocked(proc, profileType);
18155                     if (profilerInfo != null && profilerInfo.profileFd != null) {
18156                         try {
18157                             profilerInfo.profileFd.close();
18158                         } catch (IOException e) {
18159                         }
18160                     }
18161                 }
18162
18163                 return true;
18164             }
18165         } catch (RemoteException e) {
18166             throw new IllegalStateException("Process disappeared");
18167         } finally {
18168             if (profilerInfo != null && profilerInfo.profileFd != null) {
18169                 try {
18170                     profilerInfo.profileFd.close();
18171                 } catch (IOException e) {
18172                 }
18173             }
18174         }
18175     }
18176
18177     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18178         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18179                 userId, true, ALLOW_FULL_ONLY, callName, null);
18180         ProcessRecord proc = null;
18181         try {
18182             int pid = Integer.parseInt(process);
18183             synchronized (mPidsSelfLocked) {
18184                 proc = mPidsSelfLocked.get(pid);
18185             }
18186         } catch (NumberFormatException e) {
18187         }
18188
18189         if (proc == null) {
18190             ArrayMap<String, SparseArray<ProcessRecord>> all
18191                     = mProcessNames.getMap();
18192             SparseArray<ProcessRecord> procs = all.get(process);
18193             if (procs != null && procs.size() > 0) {
18194                 proc = procs.valueAt(0);
18195                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18196                     for (int i=1; i<procs.size(); i++) {
18197                         ProcessRecord thisProc = procs.valueAt(i);
18198                         if (thisProc.userId == userId) {
18199                             proc = thisProc;
18200                             break;
18201                         }
18202                     }
18203                 }
18204             }
18205         }
18206
18207         return proc;
18208     }
18209
18210     public boolean dumpHeap(String process, int userId, boolean managed,
18211             String path, ParcelFileDescriptor fd) throws RemoteException {
18212
18213         try {
18214             synchronized (this) {
18215                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18216                 // its own permission (same as profileControl).
18217                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18218                         != PackageManager.PERMISSION_GRANTED) {
18219                     throw new SecurityException("Requires permission "
18220                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18221                 }
18222
18223                 if (fd == null) {
18224                     throw new IllegalArgumentException("null fd");
18225                 }
18226
18227                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18228                 if (proc == null || proc.thread == null) {
18229                     throw new IllegalArgumentException("Unknown process: " + process);
18230                 }
18231
18232                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18233                 if (!isDebuggable) {
18234                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18235                         throw new SecurityException("Process not debuggable: " + proc);
18236                     }
18237                 }
18238
18239                 proc.thread.dumpHeap(managed, path, fd);
18240                 fd = null;
18241                 return true;
18242             }
18243         } catch (RemoteException e) {
18244             throw new IllegalStateException("Process disappeared");
18245         } finally {
18246             if (fd != null) {
18247                 try {
18248                     fd.close();
18249                 } catch (IOException e) {
18250                 }
18251             }
18252         }
18253     }
18254
18255     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18256     public void monitor() {
18257         synchronized (this) { }
18258     }
18259
18260     void onCoreSettingsChange(Bundle settings) {
18261         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18262             ProcessRecord processRecord = mLruProcesses.get(i);
18263             try {
18264                 if (processRecord.thread != null) {
18265                     processRecord.thread.setCoreSettings(settings);
18266                 }
18267             } catch (RemoteException re) {
18268                 /* ignore */
18269             }
18270         }
18271     }
18272
18273     // Multi-user methods
18274
18275     /**
18276      * Start user, if its not already running, but don't bring it to foreground.
18277      */
18278     @Override
18279     public boolean startUserInBackground(final int userId) {
18280         return startUser(userId, /* foreground */ false);
18281     }
18282
18283     /**
18284      * Start user, if its not already running, and bring it to foreground.
18285      */
18286     boolean startUserInForeground(final int userId, Dialog dlg) {
18287         boolean result = startUser(userId, /* foreground */ true);
18288         dlg.dismiss();
18289         return result;
18290     }
18291
18292     /**
18293      * Refreshes the list of users related to the current user when either a
18294      * user switch happens or when a new related user is started in the
18295      * background.
18296      */
18297     private void updateCurrentProfileIdsLocked() {
18298         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18299                 mCurrentUserId, false /* enabledOnly */);
18300         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18301         for (int i = 0; i < currentProfileIds.length; i++) {
18302             currentProfileIds[i] = profiles.get(i).id;
18303         }
18304         mCurrentProfileIds = currentProfileIds;
18305
18306         synchronized (mUserProfileGroupIdsSelfLocked) {
18307             mUserProfileGroupIdsSelfLocked.clear();
18308             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18309             for (int i = 0; i < users.size(); i++) {
18310                 UserInfo user = users.get(i);
18311                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18312                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18313                 }
18314             }
18315         }
18316     }
18317
18318     private Set getProfileIdsLocked(int userId) {
18319         Set userIds = new HashSet<Integer>();
18320         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18321                 userId, false /* enabledOnly */);
18322         for (UserInfo user : profiles) {
18323             userIds.add(Integer.valueOf(user.id));
18324         }
18325         return userIds;
18326     }
18327
18328     @Override
18329     public boolean switchUser(final int userId) {
18330         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18331         String userName;
18332         synchronized (this) {
18333             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18334             if (userInfo == null) {
18335                 Slog.w(TAG, "No user info for user #" + userId);
18336                 return false;
18337             }
18338             if (userInfo.isManagedProfile()) {
18339                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18340                 return false;
18341             }
18342             userName = userInfo.name;
18343             mTargetUserId = userId;
18344         }
18345         mHandler.removeMessages(START_USER_SWITCH_MSG);
18346         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18347         return true;
18348     }
18349
18350     private void showUserSwitchDialog(int userId, String userName) {
18351         // The dialog will show and then initiate the user switch by calling startUserInForeground
18352         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18353                 true /* above system */);
18354         d.show();
18355     }
18356
18357     private boolean startUser(final int userId, final boolean foreground) {
18358         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18359                 != PackageManager.PERMISSION_GRANTED) {
18360             String msg = "Permission Denial: switchUser() from pid="
18361                     + Binder.getCallingPid()
18362                     + ", uid=" + Binder.getCallingUid()
18363                     + " requires " + INTERACT_ACROSS_USERS_FULL;
18364             Slog.w(TAG, msg);
18365             throw new SecurityException(msg);
18366         }
18367
18368         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18369
18370         final long ident = Binder.clearCallingIdentity();
18371         try {
18372             synchronized (this) {
18373                 final int oldUserId = mCurrentUserId;
18374                 if (oldUserId == userId) {
18375                     return true;
18376                 }
18377
18378                 mStackSupervisor.setLockTaskModeLocked(null, false);
18379
18380                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18381                 if (userInfo == null) {
18382                     Slog.w(TAG, "No user info for user #" + userId);
18383                     return false;
18384                 }
18385                 if (foreground && userInfo.isManagedProfile()) {
18386                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18387                     return false;
18388                 }
18389
18390                 if (foreground) {
18391                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18392                             R.anim.screen_user_enter);
18393                 }
18394
18395                 boolean needStart = false;
18396
18397                 // If the user we are switching to is not currently started, then
18398                 // we need to start it now.
18399                 if (mStartedUsers.get(userId) == null) {
18400                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18401                     updateStartedUserArrayLocked();
18402                     needStart = true;
18403                 }
18404
18405                 final Integer userIdInt = Integer.valueOf(userId);
18406                 mUserLru.remove(userIdInt);
18407                 mUserLru.add(userIdInt);
18408
18409                 if (foreground) {
18410                     mCurrentUserId = userId;
18411                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18412                     updateCurrentProfileIdsLocked();
18413                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18414                     // Once the internal notion of the active user has switched, we lock the device
18415                     // with the option to show the user switcher on the keyguard.
18416                     mWindowManager.lockNow(null);
18417                 } else {
18418                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18419                     updateCurrentProfileIdsLocked();
18420                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18421                     mUserLru.remove(currentUserIdInt);
18422                     mUserLru.add(currentUserIdInt);
18423                 }
18424
18425                 final UserStartedState uss = mStartedUsers.get(userId);
18426
18427                 // Make sure user is in the started state.  If it is currently
18428                 // stopping, we need to knock that off.
18429                 if (uss.mState == UserStartedState.STATE_STOPPING) {
18430                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18431                     // so we can just fairly silently bring the user back from
18432                     // the almost-dead.
18433                     uss.mState = UserStartedState.STATE_RUNNING;
18434                     updateStartedUserArrayLocked();
18435                     needStart = true;
18436                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18437                     // This means ACTION_SHUTDOWN has been sent, so we will
18438                     // need to treat this as a new boot of the user.
18439                     uss.mState = UserStartedState.STATE_BOOTING;
18440                     updateStartedUserArrayLocked();
18441                     needStart = true;
18442                 }
18443
18444                 if (uss.mState == UserStartedState.STATE_BOOTING) {
18445                     // Booting up a new user, need to tell system services about it.
18446                     // Note that this is on the same handler as scheduling of broadcasts,
18447                     // which is important because it needs to go first.
18448                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18449                 }
18450
18451                 if (foreground) {
18452                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18453                             oldUserId));
18454                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18455                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18456                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18457                             oldUserId, userId, uss));
18458                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18459                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18460                 }
18461
18462                 if (needStart) {
18463                     // Send USER_STARTED broadcast
18464                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18465                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18466                             | Intent.FLAG_RECEIVER_FOREGROUND);
18467                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18468                     broadcastIntentLocked(null, null, intent,
18469                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18470                             false, false, MY_PID, Process.SYSTEM_UID, userId);
18471                 }
18472
18473                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18474                     if (userId != UserHandle.USER_OWNER) {
18475                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18476                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18477                         broadcastIntentLocked(null, null, intent, null,
18478                                 new IIntentReceiver.Stub() {
18479                                     public void performReceive(Intent intent, int resultCode,
18480                                             String data, Bundle extras, boolean ordered,
18481                                             boolean sticky, int sendingUser) {
18482                                         onUserInitialized(uss, foreground, oldUserId, userId);
18483                                     }
18484                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
18485                                 true, false, MY_PID, Process.SYSTEM_UID,
18486                                 userId);
18487                         uss.initializing = true;
18488                     } else {
18489                         getUserManagerLocked().makeInitialized(userInfo.id);
18490                     }
18491                 }
18492
18493                 if (foreground) {
18494                     if (!uss.initializing) {
18495                         moveUserToForeground(uss, oldUserId, userId);
18496                     }
18497                 } else {
18498                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
18499                 }
18500
18501                 if (needStart) {
18502                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18503                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18504                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18505                     broadcastIntentLocked(null, null, intent,
18506                             null, new IIntentReceiver.Stub() {
18507                                 @Override
18508                                 public void performReceive(Intent intent, int resultCode, String data,
18509                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18510                                         throws RemoteException {
18511                                 }
18512                             }, 0, null, null,
18513                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18514                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18515                 }
18516             }
18517         } finally {
18518             Binder.restoreCallingIdentity(ident);
18519         }
18520
18521         return true;
18522     }
18523
18524     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18525         long ident = Binder.clearCallingIdentity();
18526         try {
18527             Intent intent;
18528             if (oldUserId >= 0) {
18529                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18530                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18531                 int count = profiles.size();
18532                 for (int i = 0; i < count; i++) {
18533                     int profileUserId = profiles.get(i).id;
18534                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18535                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18536                             | Intent.FLAG_RECEIVER_FOREGROUND);
18537                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18538                     broadcastIntentLocked(null, null, intent,
18539                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18540                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18541                 }
18542             }
18543             if (newUserId >= 0) {
18544                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18545                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18546                 int count = profiles.size();
18547                 for (int i = 0; i < count; i++) {
18548                     int profileUserId = profiles.get(i).id;
18549                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18550                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18551                             | Intent.FLAG_RECEIVER_FOREGROUND);
18552                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18553                     broadcastIntentLocked(null, null, intent,
18554                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18555                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18556                 }
18557                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
18558                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18559                         | Intent.FLAG_RECEIVER_FOREGROUND);
18560                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18561                 broadcastIntentLocked(null, null, intent,
18562                         null, null, 0, null, null,
18563                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18564                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18565             }
18566         } finally {
18567             Binder.restoreCallingIdentity(ident);
18568         }
18569     }
18570
18571     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18572             final int newUserId) {
18573         final int N = mUserSwitchObservers.beginBroadcast();
18574         if (N > 0) {
18575             final IRemoteCallback callback = new IRemoteCallback.Stub() {
18576                 int mCount = 0;
18577                 @Override
18578                 public void sendResult(Bundle data) throws RemoteException {
18579                     synchronized (ActivityManagerService.this) {
18580                         if (mCurUserSwitchCallback == this) {
18581                             mCount++;
18582                             if (mCount == N) {
18583                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18584                             }
18585                         }
18586                     }
18587                 }
18588             };
18589             synchronized (this) {
18590                 uss.switching = true;
18591                 mCurUserSwitchCallback = callback;
18592             }
18593             for (int i=0; i<N; i++) {
18594                 try {
18595                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18596                             newUserId, callback);
18597                 } catch (RemoteException e) {
18598                 }
18599             }
18600         } else {
18601             synchronized (this) {
18602                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18603             }
18604         }
18605         mUserSwitchObservers.finishBroadcast();
18606     }
18607
18608     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18609         synchronized (this) {
18610             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18611             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18612         }
18613     }
18614
18615     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18616         mCurUserSwitchCallback = null;
18617         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18618         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18619                 oldUserId, newUserId, uss));
18620     }
18621
18622     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18623         synchronized (this) {
18624             if (foreground) {
18625                 moveUserToForeground(uss, oldUserId, newUserId);
18626             }
18627         }
18628
18629         completeSwitchAndInitalize(uss, newUserId, true, false);
18630     }
18631
18632     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18633         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18634         if (homeInFront) {
18635             startHomeActivityLocked(newUserId);
18636         } else {
18637             mStackSupervisor.resumeTopActivitiesLocked();
18638         }
18639         EventLogTags.writeAmSwitchUser(newUserId);
18640         getUserManagerLocked().userForeground(newUserId);
18641         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18642     }
18643
18644     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18645         completeSwitchAndInitalize(uss, newUserId, false, true);
18646     }
18647
18648     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18649             boolean clearInitializing, boolean clearSwitching) {
18650         boolean unfrozen = false;
18651         synchronized (this) {
18652             if (clearInitializing) {
18653                 uss.initializing = false;
18654                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18655             }
18656             if (clearSwitching) {
18657                 uss.switching = false;
18658             }
18659             if (!uss.switching && !uss.initializing) {
18660                 mWindowManager.stopFreezingScreen();
18661                 unfrozen = true;
18662             }
18663         }
18664         if (unfrozen) {
18665             final int N = mUserSwitchObservers.beginBroadcast();
18666             for (int i=0; i<N; i++) {
18667                 try {
18668                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18669                 } catch (RemoteException e) {
18670                 }
18671             }
18672             mUserSwitchObservers.finishBroadcast();
18673         }
18674     }
18675
18676     void scheduleStartProfilesLocked() {
18677         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18678             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18679                     DateUtils.SECOND_IN_MILLIS);
18680         }
18681     }
18682
18683     void startProfilesLocked() {
18684         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18685         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18686                 mCurrentUserId, false /* enabledOnly */);
18687         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18688         for (UserInfo user : profiles) {
18689             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18690                     && user.id != mCurrentUserId) {
18691                 toStart.add(user);
18692             }
18693         }
18694         final int n = toStart.size();
18695         int i = 0;
18696         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18697             startUserInBackground(toStart.get(i).id);
18698         }
18699         if (i < n) {
18700             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18701         }
18702     }
18703
18704     void finishUserBoot(UserStartedState uss) {
18705         synchronized (this) {
18706             if (uss.mState == UserStartedState.STATE_BOOTING
18707                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18708                 uss.mState = UserStartedState.STATE_RUNNING;
18709                 final int userId = uss.mHandle.getIdentifier();
18710                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18711                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18712                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18713                 broadcastIntentLocked(null, null, intent,
18714                         null, null, 0, null, null,
18715                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18716                         true, false, MY_PID, Process.SYSTEM_UID, userId);
18717             }
18718         }
18719     }
18720
18721     void finishUserSwitch(UserStartedState uss) {
18722         synchronized (this) {
18723             finishUserBoot(uss);
18724
18725             startProfilesLocked();
18726
18727             int num = mUserLru.size();
18728             int i = 0;
18729             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18730                 Integer oldUserId = mUserLru.get(i);
18731                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
18732                 if (oldUss == null) {
18733                     // Shouldn't happen, but be sane if it does.
18734                     mUserLru.remove(i);
18735                     num--;
18736                     continue;
18737                 }
18738                 if (oldUss.mState == UserStartedState.STATE_STOPPING
18739                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18740                     // This user is already stopping, doesn't count.
18741                     num--;
18742                     i++;
18743                     continue;
18744                 }
18745                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18746                     // Owner and current can't be stopped, but count as running.
18747                     i++;
18748                     continue;
18749                 }
18750                 // This is a user to be stopped.
18751                 stopUserLocked(oldUserId, null);
18752                 num--;
18753                 i++;
18754             }
18755         }
18756     }
18757
18758     @Override
18759     public int stopUser(final int userId, final IStopUserCallback callback) {
18760         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18761                 != PackageManager.PERMISSION_GRANTED) {
18762             String msg = "Permission Denial: switchUser() from pid="
18763                     + Binder.getCallingPid()
18764                     + ", uid=" + Binder.getCallingUid()
18765                     + " requires " + INTERACT_ACROSS_USERS_FULL;
18766             Slog.w(TAG, msg);
18767             throw new SecurityException(msg);
18768         }
18769         if (userId <= 0) {
18770             throw new IllegalArgumentException("Can't stop primary user " + userId);
18771         }
18772         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18773         synchronized (this) {
18774             return stopUserLocked(userId, callback);
18775         }
18776     }
18777
18778     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18779         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18780         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18781             return ActivityManager.USER_OP_IS_CURRENT;
18782         }
18783
18784         final UserStartedState uss = mStartedUsers.get(userId);
18785         if (uss == null) {
18786             // User is not started, nothing to do...  but we do need to
18787             // callback if requested.
18788             if (callback != null) {
18789                 mHandler.post(new Runnable() {
18790                     @Override
18791                     public void run() {
18792                         try {
18793                             callback.userStopped(userId);
18794                         } catch (RemoteException e) {
18795                         }
18796                     }
18797                 });
18798             }
18799             return ActivityManager.USER_OP_SUCCESS;
18800         }
18801
18802         if (callback != null) {
18803             uss.mStopCallbacks.add(callback);
18804         }
18805
18806         if (uss.mState != UserStartedState.STATE_STOPPING
18807                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18808             uss.mState = UserStartedState.STATE_STOPPING;
18809             updateStartedUserArrayLocked();
18810
18811             long ident = Binder.clearCallingIdentity();
18812             try {
18813                 // We are going to broadcast ACTION_USER_STOPPING and then
18814                 // once that is done send a final ACTION_SHUTDOWN and then
18815                 // stop the user.
18816                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18817                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18818                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18819                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18820                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18821                 // This is the result receiver for the final shutdown broadcast.
18822                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18823                     @Override
18824                     public void performReceive(Intent intent, int resultCode, String data,
18825                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18826                         finishUserStop(uss);
18827                     }
18828                 };
18829                 // This is the result receiver for the initial stopping broadcast.
18830                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18831                     @Override
18832                     public void performReceive(Intent intent, int resultCode, String data,
18833                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18834                         // On to the next.
18835                         synchronized (ActivityManagerService.this) {
18836                             if (uss.mState != UserStartedState.STATE_STOPPING) {
18837                                 // Whoops, we are being started back up.  Abort, abort!
18838                                 return;
18839                             }
18840                             uss.mState = UserStartedState.STATE_SHUTDOWN;
18841                         }
18842                         mBatteryStatsService.noteEvent(
18843                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18844                                 Integer.toString(userId), userId);
18845                         mSystemServiceManager.stopUser(userId);
18846                         broadcastIntentLocked(null, null, shutdownIntent,
18847                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18848                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
18849                     }
18850                 };
18851                 // Kick things off.
18852                 broadcastIntentLocked(null, null, stoppingIntent,
18853                         null, stoppingReceiver, 0, null, null,
18854                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18855                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18856             } finally {
18857                 Binder.restoreCallingIdentity(ident);
18858             }
18859         }
18860
18861         return ActivityManager.USER_OP_SUCCESS;
18862     }
18863
18864     void finishUserStop(UserStartedState uss) {
18865         final int userId = uss.mHandle.getIdentifier();
18866         boolean stopped;
18867         ArrayList<IStopUserCallback> callbacks;
18868         synchronized (this) {
18869             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18870             if (mStartedUsers.get(userId) != uss) {
18871                 stopped = false;
18872             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18873                 stopped = false;
18874             } else {
18875                 stopped = true;
18876                 // User can no longer run.
18877                 mStartedUsers.remove(userId);
18878                 mUserLru.remove(Integer.valueOf(userId));
18879                 updateStartedUserArrayLocked();
18880
18881                 // Clean up all state and processes associated with the user.
18882                 // Kill all the processes for the user.
18883                 forceStopUserLocked(userId, "finish user");
18884             }
18885
18886             // Explicitly remove the old information in mRecentTasks.
18887             removeRecentTasksForUserLocked(userId);
18888         }
18889
18890         for (int i=0; i<callbacks.size(); i++) {
18891             try {
18892                 if (stopped) callbacks.get(i).userStopped(userId);
18893                 else callbacks.get(i).userStopAborted(userId);
18894             } catch (RemoteException e) {
18895             }
18896         }
18897
18898         if (stopped) {
18899             mSystemServiceManager.cleanupUser(userId);
18900             synchronized (this) {
18901                 mStackSupervisor.removeUserLocked(userId);
18902             }
18903         }
18904     }
18905
18906     @Override
18907     public UserInfo getCurrentUser() {
18908         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18909                 != PackageManager.PERMISSION_GRANTED) && (
18910                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18911                 != PackageManager.PERMISSION_GRANTED)) {
18912             String msg = "Permission Denial: getCurrentUser() from pid="
18913                     + Binder.getCallingPid()
18914                     + ", uid=" + Binder.getCallingUid()
18915                     + " requires " + INTERACT_ACROSS_USERS;
18916             Slog.w(TAG, msg);
18917             throw new SecurityException(msg);
18918         }
18919         synchronized (this) {
18920             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18921             return getUserManagerLocked().getUserInfo(userId);
18922         }
18923     }
18924
18925     int getCurrentUserIdLocked() {
18926         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18927     }
18928
18929     @Override
18930     public boolean isUserRunning(int userId, boolean orStopped) {
18931         if (checkCallingPermission(INTERACT_ACROSS_USERS)
18932                 != PackageManager.PERMISSION_GRANTED) {
18933             String msg = "Permission Denial: isUserRunning() from pid="
18934                     + Binder.getCallingPid()
18935                     + ", uid=" + Binder.getCallingUid()
18936                     + " requires " + INTERACT_ACROSS_USERS;
18937             Slog.w(TAG, msg);
18938             throw new SecurityException(msg);
18939         }
18940         synchronized (this) {
18941             return isUserRunningLocked(userId, orStopped);
18942         }
18943     }
18944
18945     boolean isUserRunningLocked(int userId, boolean orStopped) {
18946         UserStartedState state = mStartedUsers.get(userId);
18947         if (state == null) {
18948             return false;
18949         }
18950         if (orStopped) {
18951             return true;
18952         }
18953         return state.mState != UserStartedState.STATE_STOPPING
18954                 && state.mState != UserStartedState.STATE_SHUTDOWN;
18955     }
18956
18957     @Override
18958     public int[] getRunningUserIds() {
18959         if (checkCallingPermission(INTERACT_ACROSS_USERS)
18960                 != PackageManager.PERMISSION_GRANTED) {
18961             String msg = "Permission Denial: isUserRunning() from pid="
18962                     + Binder.getCallingPid()
18963                     + ", uid=" + Binder.getCallingUid()
18964                     + " requires " + INTERACT_ACROSS_USERS;
18965             Slog.w(TAG, msg);
18966             throw new SecurityException(msg);
18967         }
18968         synchronized (this) {
18969             return mStartedUserArray;
18970         }
18971     }
18972
18973     private void updateStartedUserArrayLocked() {
18974         int num = 0;
18975         for (int i=0; i<mStartedUsers.size();  i++) {
18976             UserStartedState uss = mStartedUsers.valueAt(i);
18977             // This list does not include stopping users.
18978             if (uss.mState != UserStartedState.STATE_STOPPING
18979                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18980                 num++;
18981             }
18982         }
18983         mStartedUserArray = new int[num];
18984         num = 0;
18985         for (int i=0; i<mStartedUsers.size();  i++) {
18986             UserStartedState uss = mStartedUsers.valueAt(i);
18987             if (uss.mState != UserStartedState.STATE_STOPPING
18988                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18989                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
18990                 num++;
18991             }
18992         }
18993     }
18994
18995     @Override
18996     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18997         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18998                 != PackageManager.PERMISSION_GRANTED) {
18999             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19000                     + Binder.getCallingPid()
19001                     + ", uid=" + Binder.getCallingUid()
19002                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19003             Slog.w(TAG, msg);
19004             throw new SecurityException(msg);
19005         }
19006
19007         mUserSwitchObservers.register(observer);
19008     }
19009
19010     @Override
19011     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19012         mUserSwitchObservers.unregister(observer);
19013     }
19014
19015     private boolean userExists(int userId) {
19016         if (userId == 0) {
19017             return true;
19018         }
19019         UserManagerService ums = getUserManagerLocked();
19020         return ums != null ? (ums.getUserInfo(userId) != null) : false;
19021     }
19022
19023     int[] getUsersLocked() {
19024         UserManagerService ums = getUserManagerLocked();
19025         return ums != null ? ums.getUserIds() : new int[] { 0 };
19026     }
19027
19028     UserManagerService getUserManagerLocked() {
19029         if (mUserManager == null) {
19030             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19031             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19032         }
19033         return mUserManager;
19034     }
19035
19036     private int applyUserId(int uid, int userId) {
19037         return UserHandle.getUid(userId, uid);
19038     }
19039
19040     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19041         if (info == null) return null;
19042         ApplicationInfo newInfo = new ApplicationInfo(info);
19043         newInfo.uid = applyUserId(info.uid, userId);
19044         newInfo.dataDir = USER_DATA_DIR + userId + "/"
19045                 + info.packageName;
19046         return newInfo;
19047     }
19048
19049     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19050         if (aInfo == null
19051                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19052             return aInfo;
19053         }
19054
19055         ActivityInfo info = new ActivityInfo(aInfo);
19056         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19057         return info;
19058     }
19059
19060     private final class LocalService extends ActivityManagerInternal {
19061         @Override
19062         public void onWakefulnessChanged(int wakefulness) {
19063             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19064         }
19065
19066         @Override
19067         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19068                 String processName, String abiOverride, int uid, Runnable crashHandler) {
19069             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19070                     processName, abiOverride, uid, crashHandler);
19071         }
19072     }
19073
19074     /**
19075      * An implementation of IAppTask, that allows an app to manage its own tasks via
19076      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19077      * only the process that calls getAppTasks() can call the AppTask methods.
19078      */
19079     class AppTaskImpl extends IAppTask.Stub {
19080         private int mTaskId;
19081         private int mCallingUid;
19082
19083         public AppTaskImpl(int taskId, int callingUid) {
19084             mTaskId = taskId;
19085             mCallingUid = callingUid;
19086         }
19087
19088         private void checkCaller() {
19089             if (mCallingUid != Binder.getCallingUid()) {
19090                 throw new SecurityException("Caller " + mCallingUid
19091                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19092             }
19093         }
19094
19095         @Override
19096         public void finishAndRemoveTask() {
19097             checkCaller();
19098
19099             synchronized (ActivityManagerService.this) {
19100                 long origId = Binder.clearCallingIdentity();
19101                 try {
19102                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19103                     if (tr == null) {
19104                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19105                     }
19106                     // Only kill the process if we are not a new document
19107                     int flags = tr.getBaseIntent().getFlags();
19108                     boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19109                             Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19110                     removeTaskByIdLocked(mTaskId,
19111                             !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19112                 } finally {
19113                     Binder.restoreCallingIdentity(origId);
19114                 }
19115             }
19116         }
19117
19118         @Override
19119         public ActivityManager.RecentTaskInfo getTaskInfo() {
19120             checkCaller();
19121
19122             synchronized (ActivityManagerService.this) {
19123                 long origId = Binder.clearCallingIdentity();
19124                 try {
19125                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19126                     if (tr == null) {
19127                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19128                     }
19129                     return createRecentTaskInfoFromTaskRecord(tr);
19130                 } finally {
19131                     Binder.restoreCallingIdentity(origId);
19132                 }
19133             }
19134         }
19135
19136         @Override
19137         public void moveToFront() {
19138             checkCaller();
19139
19140             final TaskRecord tr;
19141             synchronized (ActivityManagerService.this) {
19142                 tr = recentTaskForIdLocked(mTaskId);
19143                 if (tr == null) {
19144                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19145                 }
19146                 if (tr.getRootActivity() != null) {
19147                     moveTaskToFrontLocked(tr.taskId, 0, null);
19148                     return;
19149                 }
19150             }
19151
19152             startActivityFromRecentsInner(tr.taskId, null);
19153         }
19154
19155         @Override
19156         public int startActivity(IBinder whoThread, String callingPackage,
19157                 Intent intent, String resolvedType, Bundle options) {
19158             checkCaller();
19159
19160             int callingUser = UserHandle.getCallingUserId();
19161             TaskRecord tr;
19162             IApplicationThread appThread;
19163             synchronized (ActivityManagerService.this) {
19164                 tr = recentTaskForIdLocked(mTaskId);
19165                 if (tr == null) {
19166                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19167                 }
19168                 appThread = ApplicationThreadNative.asInterface(whoThread);
19169                 if (appThread == null) {
19170                     throw new IllegalArgumentException("Bad app thread " + appThread);
19171                 }
19172             }
19173             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19174                     resolvedType, null, null, null, null, 0, 0, null, null,
19175                     null, options, callingUser, null, tr);
19176         }
19177
19178         @Override
19179         public void setExcludeFromRecents(boolean exclude) {
19180             checkCaller();
19181
19182             synchronized (ActivityManagerService.this) {
19183                 long origId = Binder.clearCallingIdentity();
19184                 try {
19185                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19186                     if (tr == null) {
19187                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19188                     }
19189                     Intent intent = tr.getBaseIntent();
19190                     if (exclude) {
19191                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19192                     } else {
19193                         intent.setFlags(intent.getFlags()
19194                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19195                     }
19196                 } finally {
19197                     Binder.restoreCallingIdentity(origId);
19198                 }
19199             }
19200         }
19201     }
19202 }