OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.server.am;
18
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
34
35 import android.Manifest;
36 import android.app.AppOpsManager;
37 import android.app.ApplicationThreadNative;
38 import android.app.IActivityContainer;
39 import android.app.IActivityContainerCallback;
40 import android.app.IAppTask;
41 import android.app.ITaskStackListener;
42 import android.app.ProfilerInfo;
43 import android.app.admin.DevicePolicyManager;
44 import android.app.usage.UsageEvents;
45 import android.app.usage.UsageStatsManagerInternal;
46 import android.appwidget.AppWidgetManager;
47 import android.content.res.Resources;
48 import android.graphics.Bitmap;
49 import android.graphics.Point;
50 import android.graphics.Rect;
51 import android.os.BatteryStats;
52 import android.os.PersistableBundle;
53 import android.os.storage.IMountService;
54 import android.os.storage.StorageManager;
55 import android.service.voice.IVoiceInteractionSession;
56 import android.util.ArrayMap;
57 import android.util.ArraySet;
58 import android.util.SparseIntArray;
59
60 import android.view.Display;
61 import com.android.internal.R;
62 import com.android.internal.annotations.GuardedBy;
63 import com.android.internal.app.IAppOpsService;
64 import com.android.internal.app.IVoiceInteractor;
65 import com.android.internal.app.ProcessMap;
66 import com.android.internal.app.ProcessStats;
67 import com.android.internal.os.BackgroundThread;
68 import com.android.internal.os.BatteryStatsImpl;
69 import com.android.internal.os.ProcessCpuTracker;
70 import com.android.internal.os.TransferPipe;
71 import com.android.internal.os.Zygote;
72 import com.android.internal.util.FastPrintWriter;
73 import com.android.internal.util.FastXmlSerializer;
74 import com.android.internal.util.MemInfoReader;
75 import com.android.internal.util.Preconditions;
76 import com.android.server.AppOpsService;
77 import com.android.server.AttributeCache;
78 import com.android.server.IntentResolver;
79 import com.android.server.LocalServices;
80 import com.android.server.ServiceThread;
81 import com.android.server.SystemService;
82 import com.android.server.SystemServiceManager;
83 import com.android.server.Watchdog;
84 import com.android.server.am.ActivityStack.ActivityState;
85 import com.android.server.firewall.IntentFirewall;
86 import com.android.server.pm.Installer;
87 import com.android.server.pm.UserManagerService;
88 import com.android.server.statusbar.StatusBarManagerInternal;
89 import com.android.server.wm.AppTransition;
90 import com.android.server.wm.WindowManagerService;
91 import com.google.android.collect.Lists;
92 import com.google.android.collect.Maps;
93
94 import libcore.io.IoUtils;
95
96 import org.xmlpull.v1.XmlPullParser;
97 import org.xmlpull.v1.XmlPullParserException;
98 import org.xmlpull.v1.XmlSerializer;
99
100 import android.app.Activity;
101 import android.app.ActivityManager;
102 import android.app.ActivityManager.RunningTaskInfo;
103 import android.app.ActivityManager.StackInfo;
104 import android.app.ActivityManagerInternal;
105 import android.app.ActivityManagerNative;
106 import android.app.ActivityOptions;
107 import android.app.ActivityThread;
108 import android.app.AlertDialog;
109 import android.app.AppGlobals;
110 import android.app.ApplicationErrorReport;
111 import android.app.Dialog;
112 import android.app.IActivityController;
113 import android.app.IApplicationThread;
114 import android.app.IInstrumentationWatcher;
115 import android.app.INotificationManager;
116 import android.app.IProcessObserver;
117 import android.app.IServiceConnection;
118 import android.app.IStopUserCallback;
119 import android.app.IUiAutomationConnection;
120 import android.app.IUserSwitchObserver;
121 import android.app.Instrumentation;
122 import android.app.Notification;
123 import android.app.NotificationManager;
124 import android.app.PendingIntent;
125 import android.app.backup.IBackupManager;
126 import android.content.ActivityNotFoundException;
127 import android.content.BroadcastReceiver;
128 import android.content.ClipData;
129 import android.content.ComponentCallbacks2;
130 import android.content.ComponentName;
131 import android.content.ContentProvider;
132 import android.content.ContentResolver;
133 import android.content.Context;
134 import android.content.DialogInterface;
135 import android.content.IContentProvider;
136 import android.content.IIntentReceiver;
137 import android.content.IIntentSender;
138 import android.content.Intent;
139 import android.content.IntentFilter;
140 import android.content.IntentSender;
141 import android.content.pm.ActivityInfo;
142 import android.content.pm.ApplicationInfo;
143 import android.content.pm.ConfigurationInfo;
144 import android.content.pm.IPackageDataObserver;
145 import android.content.pm.IPackageManager;
146 import android.content.pm.InstrumentationInfo;
147 import android.content.pm.PackageInfo;
148 import android.content.pm.PackageManager;
149 import android.content.pm.ParceledListSlice;
150 import android.content.pm.UserInfo;
151 import android.content.pm.PackageManager.NameNotFoundException;
152 import android.content.pm.PathPermission;
153 import android.content.pm.ProviderInfo;
154 import android.content.pm.ResolveInfo;
155 import android.content.pm.ServiceInfo;
156 import android.content.res.CompatibilityInfo;
157 import android.content.res.Configuration;
158 import android.net.Proxy;
159 import android.net.ProxyInfo;
160 import android.net.Uri;
161 import android.os.Binder;
162 import android.os.Build;
163 import android.os.Bundle;
164 import android.os.Debug;
165 import android.os.DropBoxManager;
166 import android.os.Environment;
167 import android.os.FactoryTest;
168 import android.os.FileObserver;
169 import android.os.FileUtils;
170 import android.os.Handler;
171 import android.os.IBinder;
172 import android.os.IPermissionController;
173 import android.os.IRemoteCallback;
174 import android.os.IUserManager;
175 import android.os.Looper;
176 import android.os.Message;
177 import android.os.Parcel;
178 import android.os.ParcelFileDescriptor;
179 import android.os.PowerManagerInternal;
180 import android.os.Process;
181 import android.os.RemoteCallbackList;
182 import android.os.RemoteException;
183 import android.os.SELinux;
184 import android.os.ServiceManager;
185 import android.os.StrictMode;
186 import android.os.SystemClock;
187 import android.os.SystemProperties;
188 import android.os.UpdateLock;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.provider.Downloads;
192 import android.provider.Settings;
193 import android.text.format.DateUtils;
194 import android.text.format.Time;
195 import android.util.AtomicFile;
196 import android.util.EventLog;
197 import android.util.Log;
198 import android.util.Pair;
199 import android.util.PrintWriterPrinter;
200 import android.util.Slog;
201 import android.util.SparseArray;
202 import android.util.TimeUtils;
203 import android.util.Xml;
204 import android.view.Gravity;
205 import android.view.LayoutInflater;
206 import android.view.View;
207 import android.view.WindowManager;
208
209 import dalvik.system.VMRuntime;
210
211 import java.io.BufferedInputStream;
212 import java.io.BufferedOutputStream;
213 import java.io.DataInputStream;
214 import java.io.DataOutputStream;
215 import java.io.File;
216 import java.io.FileDescriptor;
217 import java.io.FileInputStream;
218 import java.io.FileNotFoundException;
219 import java.io.FileOutputStream;
220 import java.io.IOException;
221 import java.io.InputStreamReader;
222 import java.io.PrintWriter;
223 import java.io.StringWriter;
224 import java.lang.ref.WeakReference;
225 import java.util.ArrayList;
226 import java.util.Arrays;
227 import java.util.Collections;
228 import java.util.Comparator;
229 import java.util.HashMap;
230 import java.util.HashSet;
231 import java.util.Iterator;
232 import java.util.List;
233 import java.util.Locale;
234 import java.util.Map;
235 import java.util.Set;
236 import java.util.concurrent.atomic.AtomicBoolean;
237 import java.util.concurrent.atomic.AtomicLong;
238
239 public final class ActivityManagerService extends ActivityManagerNative
240         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
241
242     private static final String USER_DATA_DIR = "/data/user/";
243     // File that stores last updated system version and called preboot receivers
244     static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
245
246     static final String TAG = "ActivityManager";
247     static final String TAG_MU = "ActivityManagerServiceMU";
248     static final boolean DEBUG = false;
249     static final boolean localLOGV = DEBUG;
250     static final boolean DEBUG_BACKUP = localLOGV || false;
251     static final boolean DEBUG_BROADCAST = localLOGV || false;
252     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
253     static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
254     static final boolean DEBUG_CLEANUP = localLOGV || false;
255     static final boolean DEBUG_CONFIGURATION = localLOGV || false;
256     static final boolean DEBUG_FOCUS = false;
257     static final boolean DEBUG_IMMERSIVE = localLOGV || false;
258     static final boolean DEBUG_MU = localLOGV || false;
259     static final boolean DEBUG_OOM_ADJ = localLOGV || false;
260     static final boolean DEBUG_LRU = localLOGV || false;
261     static final boolean DEBUG_PAUSE = localLOGV || false;
262     static final boolean DEBUG_POWER = localLOGV || false;
263     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
264     static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
265     static final boolean DEBUG_PROCESSES = localLOGV || false;
266     static final boolean DEBUG_PROVIDER = localLOGV || false;
267     static final boolean DEBUG_RESULTS = localLOGV || false;
268     static final boolean DEBUG_SERVICE = localLOGV || false;
269     static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
270     static final boolean DEBUG_STACK = localLOGV || false;
271     static final boolean DEBUG_SWITCH = localLOGV || false;
272     static final boolean DEBUG_TASKS = localLOGV || false;
273     static final boolean DEBUG_THUMBNAILS = localLOGV || false;
274     static final boolean DEBUG_TRANSITION = localLOGV || false;
275     static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
276     static final boolean DEBUG_USER_LEAVING = localLOGV || false;
277     static final boolean DEBUG_VISBILITY = localLOGV || false;
278     static final boolean DEBUG_PSS = localLOGV || false;
279     static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
280     static final boolean DEBUG_RECENTS = localLOGV || false;
281     static final boolean VALIDATE_TOKENS = false;
282     static final boolean SHOW_ACTIVITY_START_TIME = true;
283
284     // Control over CPU and battery monitoring.
285     static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
286     static final boolean MONITOR_CPU_USAGE = true;
287     static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
288     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
289     static final boolean MONITOR_THREAD_CPU_USAGE = false;
290
291     // The flags that are set for all calls we make to the package manager.
292     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
293
294     private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
295
296     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
297
298     // Maximum number recent bitmaps to keep in memory.
299     static final int MAX_RECENT_BITMAPS = 3;
300
301     // Amount of time after a call to stopAppSwitches() during which we will
302     // prevent further untrusted switches from happening.
303     static final long APP_SWITCH_DELAY_TIME = 5*1000;
304
305     // How long we wait for a launched process to attach to the activity manager
306     // before we decide it's never going to come up for real.
307     static final int PROC_START_TIMEOUT = 10*1000;
308
309     // How long we wait for a launched process to attach to the activity manager
310     // before we decide it's never going to come up for real, when the process was
311     // started with a wrapper for instrumentation (such as Valgrind) because it
312     // could take much longer than usual.
313     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
314
315     // How long to wait after going idle before forcing apps to GC.
316     static final int GC_TIMEOUT = 5*1000;
317
318     // The minimum amount of time between successive GC requests for a process.
319     static final int GC_MIN_INTERVAL = 60*1000;
320
321     // The minimum amount of time between successive PSS requests for a process.
322     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
323
324     // The minimum amount of time between successive PSS requests for a process
325     // when the request is due to the memory state being lowered.
326     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
327
328     // The rate at which we check for apps using excessive power -- 15 mins.
329     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
330
331     // The minimum sample duration we will allow before deciding we have
332     // enough data on wake locks to start killing things.
333     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334
335     // The minimum sample duration we will allow before deciding we have
336     // enough data on CPU usage to start killing things.
337     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
338
339     // How long we allow a receiver to run before giving up on it.
340     static final int BROADCAST_FG_TIMEOUT = 10*1000;
341     static final int BROADCAST_BG_TIMEOUT = 60*1000;
342
343     // How long we wait until we timeout on key dispatching.
344     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
345
346     // How long we wait until we timeout on key dispatching during instrumentation.
347     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
348
349     // Amount of time we wait for observers to handle a user switch before
350     // giving up on them and unfreezing the screen.
351     static final int USER_SWITCH_TIMEOUT = 2*1000;
352
353     // Maximum number of users we allow to be running at a time.
354     static final int MAX_RUNNING_USERS = 3;
355
356     // How long to wait in getAssistContextExtras for the activity and foreground services
357     // to respond with the result.
358     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
359
360     // Maximum number of persisted Uri grants a package is allowed
361     static final int MAX_PERSISTED_URI_GRANTS = 128;
362
363     static final int MY_PID = Process.myPid();
364
365     static final String[] EMPTY_STRING_ARRAY = new String[0];
366
367     // How many bytes to write into the dropbox log before truncating
368     static final int DROPBOX_MAX_SIZE = 256 * 1024;
369
370     // Access modes for handleIncomingUser.
371     static final int ALLOW_NON_FULL = 0;
372     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
373     static final int ALLOW_FULL_ONLY = 2;
374
375     static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
376
377     // Delay in notifying task stack change listeners (in millis)
378     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
379
380     // Necessary ApplicationInfo flags to mark an app as persistent
381     private static final int PERSISTENT_MASK =
382             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
383
384     /** All system services */
385     SystemServiceManager mSystemServiceManager;
386
387     private Installer mInstaller;
388
389     /** Run all ActivityStacks through this */
390     ActivityStackSupervisor mStackSupervisor;
391
392     /** Task stack change listeners. */
393     private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
394             new RemoteCallbackList<ITaskStackListener>();
395
396     public IntentFirewall mIntentFirewall;
397
398     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
399     // default actuion automatically.  Important for devices without direct input
400     // devices.
401     private boolean mShowDialogs = true;
402
403     BroadcastQueue mFgBroadcastQueue;
404     BroadcastQueue mBgBroadcastQueue;
405     // Convenient for easy iteration over the queues. Foreground is first
406     // so that dispatch of foreground broadcasts gets precedence.
407     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
408
409     BroadcastQueue broadcastQueueForIntent(Intent intent) {
410         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
411         if (DEBUG_BACKGROUND_BROADCAST) {
412             Slog.i(TAG, "Broadcast intent " + intent + " on "
413                     + (isFg ? "foreground" : "background")
414                     + " queue");
415         }
416         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
417     }
418
419     BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
420         for (BroadcastQueue queue : mBroadcastQueues) {
421             BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
422             if (r != null) {
423                 return r;
424             }
425         }
426         return null;
427     }
428
429     /**
430      * Activity we have told the window manager to have key focus.
431      */
432     ActivityRecord mFocusedActivity = null;
433
434     /**
435      * List of intents that were used to start the most recent tasks.
436      */
437     ArrayList<TaskRecord> mRecentTasks;
438     ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
439
440     /**
441      * For addAppTask: cached of the last activity component that was added.
442      */
443     ComponentName mLastAddedTaskComponent;
444
445     /**
446      * For addAppTask: cached of the last activity uid that was added.
447      */
448     int mLastAddedTaskUid;
449
450     /**
451      * For addAppTask: cached of the last ActivityInfo that was added.
452      */
453     ActivityInfo mLastAddedTaskActivity;
454
455     public class PendingAssistExtras extends Binder implements Runnable {
456         public final ActivityRecord activity;
457         public final Bundle extras;
458         public final Intent intent;
459         public final String hint;
460         public final int userHandle;
461         public boolean haveResult = false;
462         public Bundle result = null;
463         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
464                 String _hint, int _userHandle) {
465             activity = _activity;
466             extras = _extras;
467             intent = _intent;
468             hint = _hint;
469             userHandle = _userHandle;
470         }
471         @Override
472         public void run() {
473             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
474             synchronized (this) {
475                 haveResult = true;
476                 notifyAll();
477             }
478         }
479     }
480
481     final ArrayList<PendingAssistExtras> mPendingAssistExtras
482             = new ArrayList<PendingAssistExtras>();
483
484     /**
485      * Process management.
486      */
487     final ProcessList mProcessList = new ProcessList();
488
489     /**
490      * All of the applications we currently have running organized by name.
491      * The keys are strings of the application package name (as
492      * returned by the package manager), and the keys are ApplicationRecord
493      * objects.
494      */
495     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
496
497     /**
498      * Tracking long-term execution of processes to look for abuse and other
499      * bad app behavior.
500      */
501     final ProcessStatsService mProcessStats;
502
503     /**
504      * The currently running isolated processes.
505      */
506     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
507
508     /**
509      * Counter for assigning isolated process uids, to avoid frequently reusing the
510      * same ones.
511      */
512     int mNextIsolatedProcessUid = 0;
513
514     /**
515      * The currently running heavy-weight process, if any.
516      */
517     ProcessRecord mHeavyWeightProcess = null;
518
519     /**
520      * The last time that various processes have crashed.
521      */
522     final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
523
524     /**
525      * Information about a process that is currently marked as bad.
526      */
527     static final class BadProcessInfo {
528         BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
529             this.time = time;
530             this.shortMsg = shortMsg;
531             this.longMsg = longMsg;
532             this.stack = stack;
533         }
534
535         final long time;
536         final String shortMsg;
537         final String longMsg;
538         final String stack;
539     }
540
541     /**
542      * Set of applications that we consider to be bad, and will reject
543      * incoming broadcasts from (which the user has no control over).
544      * Processes are added to this set when they have crashed twice within
545      * a minimum amount of time; they are removed from it when they are
546      * later restarted (hopefully due to some user action).  The value is the
547      * time it was added to the list.
548      */
549     final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
550
551     /**
552      * All of the processes we currently have running organized by pid.
553      * The keys are the pid running the application.
554      *
555      * <p>NOTE: This object is protected by its own lock, NOT the global
556      * activity manager lock!
557      */
558     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
559
560     /**
561      * All of the processes that have been forced to be foreground.  The key
562      * is the pid of the caller who requested it (we hold a death
563      * link on it).
564      */
565     abstract class ForegroundToken implements IBinder.DeathRecipient {
566         int pid;
567         IBinder token;
568     }
569     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
570
571     /**
572      * List of records for processes that someone had tried to start before the
573      * system was ready.  We don't start them at that point, but ensure they
574      * are started by the time booting is complete.
575      */
576     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
577
578     /**
579      * List of persistent applications that are in the process
580      * of being started.
581      */
582     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
583
584     /**
585      * Processes that are being forcibly torn down.
586      */
587     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
588
589     /**
590      * List of running applications, sorted by recent usage.
591      * The first entry in the list is the least recently used.
592      */
593     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
594
595     /**
596      * Where in mLruProcesses that the processes hosting activities start.
597      */
598     int mLruProcessActivityStart = 0;
599
600     /**
601      * Where in mLruProcesses that the processes hosting services start.
602      * This is after (lower index) than mLruProcessesActivityStart.
603      */
604     int mLruProcessServiceStart = 0;
605
606     /**
607      * List of processes that should gc as soon as things are idle.
608      */
609     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
610
611     /**
612      * Processes we want to collect PSS data from.
613      */
614     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
615
616     /**
617      * Last time we requested PSS data of all processes.
618      */
619     long mLastFullPssTime = SystemClock.uptimeMillis();
620
621     /**
622      * If set, the next time we collect PSS data we should do a full collection
623      * with data from native processes and the kernel.
624      */
625     boolean mFullPssPending = false;
626
627     /**
628      * This is the process holding what we currently consider to be
629      * the "home" activity.
630      */
631     ProcessRecord mHomeProcess;
632
633     /**
634      * This is the process holding the activity the user last visited that
635      * is in a different process from the one they are currently in.
636      */
637     ProcessRecord mPreviousProcess;
638
639     /**
640      * The time at which the previous process was last visible.
641      */
642     long mPreviousProcessVisibleTime;
643
644     /**
645      * Which uses have been started, so are allowed to run code.
646      */
647     final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
648
649     /**
650      * LRU list of history of current users.  Most recently current is at the end.
651      */
652     final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
653
654     /**
655      * Constant array of the users that are currently started.
656      */
657     int[] mStartedUserArray = new int[] { 0 };
658
659     /**
660      * Registered observers of the user switching mechanics.
661      */
662     final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
663             = new RemoteCallbackList<IUserSwitchObserver>();
664
665     /**
666      * Currently active user switch.
667      */
668     Object mCurUserSwitchCallback;
669
670     /**
671      * Packages that the user has asked to have run in screen size
672      * compatibility mode instead of filling the screen.
673      */
674     final CompatModePackages mCompatModePackages;
675
676     /**
677      * Set of IntentSenderRecord objects that are currently active.
678      */
679     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
680             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
681
682     /**
683      * Fingerprints (hashCode()) of stack traces that we've
684      * already logged DropBox entries for.  Guarded by itself.  If
685      * something (rogue user app) forces this over
686      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
687      */
688     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
689     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
690
691     /**
692      * Strict Mode background batched logging state.
693      *
694      * The string buffer is guarded by itself, and its lock is also
695      * used to determine if another batched write is already
696      * in-flight.
697      */
698     private final StringBuilder mStrictModeBuffer = new StringBuilder();
699
700     /**
701      * Keeps track of all IIntentReceivers that have been registered for
702      * broadcasts.  Hash keys are the receiver IBinder, hash value is
703      * a ReceiverList.
704      */
705     final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
706             new HashMap<IBinder, ReceiverList>();
707
708     /**
709      * Resolver for broadcast intents to registered receivers.
710      * Holds BroadcastFilter (subclass of IntentFilter).
711      */
712     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
713             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
714         @Override
715         protected boolean allowFilterResult(
716                 BroadcastFilter filter, List<BroadcastFilter> dest) {
717             IBinder target = filter.receiverList.receiver.asBinder();
718             for (int i=dest.size()-1; i>=0; i--) {
719                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
720                     return false;
721                 }
722             }
723             return true;
724         }
725
726         @Override
727         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
728             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
729                     || userId == filter.owningUserId) {
730                 return super.newResult(filter, match, userId);
731             }
732             return null;
733         }
734
735         @Override
736         protected BroadcastFilter[] newArray(int size) {
737             return new BroadcastFilter[size];
738         }
739
740         @Override
741         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
742             return packageName.equals(filter.packageName);
743         }
744     };
745
746     /**
747      * State of all active sticky broadcasts per user.  Keys are the action of the
748      * sticky Intent, values are an ArrayList of all broadcasted intents with
749      * that action (which should usually be one).  The SparseArray is keyed
750      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
751      * for stickies that are sent to all users.
752      */
753     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
754             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
755
756     final ActiveServices mServices;
757
758     final static class Association {
759         final int mSourceUid;
760         final String mSourceProcess;
761         final int mTargetUid;
762         final ComponentName mTargetComponent;
763         final String mTargetProcess;
764
765         int mCount;
766         long mTime;
767
768         int mNesting;
769         long mStartTime;
770
771         Association(int sourceUid, String sourceProcess, int targetUid,
772                 ComponentName targetComponent, String targetProcess) {
773             mSourceUid = sourceUid;
774             mSourceProcess = sourceProcess;
775             mTargetUid = targetUid;
776             mTargetComponent = targetComponent;
777             mTargetProcess = targetProcess;
778         }
779     }
780
781     /**
782      * When service association tracking is enabled, this is all of the associations we
783      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
784      * -> association data.
785      */
786     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
787             mAssociations = new SparseArray<>();
788     boolean mTrackingAssociations;
789
790     /**
791      * Backup/restore process management
792      */
793     String mBackupAppName = null;
794     BackupRecord mBackupTarget = null;
795
796     final ProviderMap mProviderMap;
797
798     /**
799      * List of content providers who have clients waiting for them.  The
800      * application is currently being launched and the provider will be
801      * removed from this list once it is published.
802      */
803     final ArrayList<ContentProviderRecord> mLaunchingProviders
804             = new ArrayList<ContentProviderRecord>();
805
806     /**
807      * File storing persisted {@link #mGrantedUriPermissions}.
808      */
809     private final AtomicFile mGrantFile;
810
811     /** XML constants used in {@link #mGrantFile} */
812     private static final String TAG_URI_GRANTS = "uri-grants";
813     private static final String TAG_URI_GRANT = "uri-grant";
814     private static final String ATTR_USER_HANDLE = "userHandle";
815     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
816     private static final String ATTR_TARGET_USER_ID = "targetUserId";
817     private static final String ATTR_SOURCE_PKG = "sourcePkg";
818     private static final String ATTR_TARGET_PKG = "targetPkg";
819     private static final String ATTR_URI = "uri";
820     private static final String ATTR_MODE_FLAGS = "modeFlags";
821     private static final String ATTR_CREATED_TIME = "createdTime";
822     private static final String ATTR_PREFIX = "prefix";
823
824     /**
825      * Global set of specific {@link Uri} permissions that have been granted.
826      * This optimized lookup structure maps from {@link UriPermission#targetUid}
827      * to {@link UriPermission#uri} to {@link UriPermission}.
828      */
829     @GuardedBy("this")
830     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
831             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
832
833     public static class GrantUri {
834         public final int sourceUserId;
835         public final Uri uri;
836         public boolean prefix;
837
838         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
839             this.sourceUserId = sourceUserId;
840             this.uri = uri;
841             this.prefix = prefix;
842         }
843
844         @Override
845         public int hashCode() {
846             int hashCode = 1;
847             hashCode = 31 * hashCode + sourceUserId;
848             hashCode = 31 * hashCode + uri.hashCode();
849             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
850             return hashCode;
851         }
852
853         @Override
854         public boolean equals(Object o) {
855             if (o instanceof GrantUri) {
856                 GrantUri other = (GrantUri) o;
857                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
858                         && prefix == other.prefix;
859             }
860             return false;
861         }
862
863         @Override
864         public String toString() {
865             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
866             if (prefix) result += " [prefix]";
867             return result;
868         }
869
870         public String toSafeString() {
871             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
872             if (prefix) result += " [prefix]";
873             return result;
874         }
875
876         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
877             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
878                     ContentProvider.getUriWithoutUserId(uri), false);
879         }
880     }
881
882     CoreSettingsObserver mCoreSettingsObserver;
883
884     /**
885      * Thread-local storage used to carry caller permissions over through
886      * indirect content-provider access.
887      */
888     private class Identity {
889         public final IBinder token;
890         public final int pid;
891         public final int uid;
892
893         Identity(IBinder _token, int _pid, int _uid) {
894             token = _token;
895             pid = _pid;
896             uid = _uid;
897         }
898     }
899
900     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
901
902     /**
903      * All information we have collected about the runtime performance of
904      * any user id that can impact battery performance.
905      */
906     final BatteryStatsService mBatteryStatsService;
907
908     /**
909      * Information about component usage
910      */
911     UsageStatsManagerInternal mUsageStatsService;
912
913     /**
914      * Information about and control over application operations
915      */
916     final AppOpsService mAppOpsService;
917
918     /**
919      * Save recent tasks information across reboots.
920      */
921     final TaskPersister mTaskPersister;
922
923     /**
924      * Current configuration information.  HistoryRecord objects are given
925      * a reference to this object to indicate which configuration they are
926      * currently running in, so this object must be kept immutable.
927      */
928     Configuration mConfiguration = new Configuration();
929
930     /**
931      * Current sequencing integer of the configuration, for skipping old
932      * configurations.
933      */
934     int mConfigurationSeq = 0;
935
936     /**
937      * Hardware-reported OpenGLES version.
938      */
939     final int GL_ES_VERSION;
940
941     /**
942      * List of initialization arguments to pass to all processes when binding applications to them.
943      * For example, references to the commonly used services.
944      */
945     HashMap<String, IBinder> mAppBindArgs;
946     HashMap<String, IBinder> mIsolatedAppBindArgs;
947
948     /**
949      * Temporary to avoid allocations.  Protected by main lock.
950      */
951     final StringBuilder mStringBuilder = new StringBuilder(256);
952
953     /**
954      * Used to control how we initialize the service.
955      */
956     ComponentName mTopComponent;
957     String mTopAction = Intent.ACTION_MAIN;
958     String mTopData;
959     boolean mProcessesReady = false;
960     boolean mSystemReady = false;
961     boolean mBooting = false;
962     boolean mCallFinishBooting = false;
963     boolean mBootAnimationComplete = false;
964     boolean mWaitingUpdate = false;
965     boolean mDidUpdate = false;
966     boolean mOnBattery = false;
967     boolean mLaunchWarningShown = false;
968
969     Context mContext;
970
971     int mFactoryTest;
972
973     boolean mCheckedForSetup;
974
975     /**
976      * The time at which we will allow normal application switches again,
977      * after a call to {@link #stopAppSwitches()}.
978      */
979     long mAppSwitchesAllowedTime;
980
981     /**
982      * This is set to true after the first switch after mAppSwitchesAllowedTime
983      * is set; any switches after that will clear the time.
984      */
985     boolean mDidAppSwitch;
986
987     /**
988      * Last time (in realtime) at which we checked for power usage.
989      */
990     long mLastPowerCheckRealtime;
991
992     /**
993      * Last time (in uptime) at which we checked for power usage.
994      */
995     long mLastPowerCheckUptime;
996
997     /**
998      * Set while we are wanting to sleep, to prevent any
999      * activities from being started/resumed.
1000      */
1001     private boolean mSleeping = false;
1002
1003     /**
1004      * Set while we are running a voice interaction.  This overrides
1005      * sleeping while it is active.
1006      */
1007     private boolean mRunningVoice = false;
1008
1009     /**
1010      * State of external calls telling us if the device is awake or asleep.
1011      */
1012     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1013
1014     static final int LOCK_SCREEN_HIDDEN = 0;
1015     static final int LOCK_SCREEN_LEAVING = 1;
1016     static final int LOCK_SCREEN_SHOWN = 2;
1017     /**
1018      * State of external call telling us if the lock screen is shown.
1019      */
1020     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1021
1022     /**
1023      * Set if we are shutting down the system, similar to sleeping.
1024      */
1025     boolean mShuttingDown = false;
1026
1027     /**
1028      * Current sequence id for oom_adj computation traversal.
1029      */
1030     int mAdjSeq = 0;
1031
1032     /**
1033      * Current sequence id for process LRU updating.
1034      */
1035     int mLruSeq = 0;
1036
1037     /**
1038      * Keep track of the non-cached/empty process we last found, to help
1039      * determine how to distribute cached/empty processes next time.
1040      */
1041     int mNumNonCachedProcs = 0;
1042
1043     /**
1044      * Keep track of the number of cached hidden procs, to balance oom adj
1045      * distribution between those and empty procs.
1046      */
1047     int mNumCachedHiddenProcs = 0;
1048
1049     /**
1050      * Keep track of the number of service processes we last found, to
1051      * determine on the next iteration which should be B services.
1052      */
1053     int mNumServiceProcs = 0;
1054     int mNewNumAServiceProcs = 0;
1055     int mNewNumServiceProcs = 0;
1056
1057     /**
1058      * Allow the current computed overall memory level of the system to go down?
1059      * This is set to false when we are killing processes for reasons other than
1060      * memory management, so that the now smaller process list will not be taken as
1061      * an indication that memory is tighter.
1062      */
1063     boolean mAllowLowerMemLevel = false;
1064
1065     /**
1066      * The last computed memory level, for holding when we are in a state that
1067      * processes are going away for other reasons.
1068      */
1069     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1070
1071     /**
1072      * The last total number of process we have, to determine if changes actually look
1073      * like a shrinking number of process due to lower RAM.
1074      */
1075     int mLastNumProcesses;
1076
1077     /**
1078      * The uptime of the last time we performed idle maintenance.
1079      */
1080     long mLastIdleTime = SystemClock.uptimeMillis();
1081
1082     /**
1083      * Total time spent with RAM that has been added in the past since the last idle time.
1084      */
1085     long mLowRamTimeSinceLastIdle = 0;
1086
1087     /**
1088      * If RAM is currently low, when that horrible situation started.
1089      */
1090     long mLowRamStartTime = 0;
1091
1092     /**
1093      * For reporting to battery stats the current top application.
1094      */
1095     private String mCurResumedPackage = null;
1096     private int mCurResumedUid = -1;
1097
1098     /**
1099      * For reporting to battery stats the apps currently running foreground
1100      * service.  The ProcessMap is package/uid tuples; each of these contain
1101      * an array of the currently foreground processes.
1102      */
1103     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1104             = new ProcessMap<ArrayList<ProcessRecord>>();
1105
1106     /**
1107      * This is set if we had to do a delayed dexopt of an app before launching
1108      * it, to increase the ANR timeouts in that case.
1109      */
1110     boolean mDidDexOpt;
1111
1112     /**
1113      * Set if the systemServer made a call to enterSafeMode.
1114      */
1115     boolean mSafeMode;
1116
1117     /**
1118      * If true, we are running under a test environment so will sample PSS from processes
1119      * much more rapidly to try to collect better data when the tests are rapidly
1120      * running through apps.
1121      */
1122     boolean mTestPssMode = false;
1123
1124     String mDebugApp = null;
1125     boolean mWaitForDebugger = false;
1126     boolean mDebugTransient = false;
1127     String mOrigDebugApp = null;
1128     boolean mOrigWaitForDebugger = false;
1129     boolean mAlwaysFinishActivities = false;
1130     IActivityController mController = null;
1131     String mProfileApp = null;
1132     ProcessRecord mProfileProc = null;
1133     String mProfileFile;
1134     ParcelFileDescriptor mProfileFd;
1135     int mSamplingInterval = 0;
1136     boolean mAutoStopProfiler = false;
1137     int mProfileType = 0;
1138     String mOpenGlTraceApp = null;
1139
1140     final long[] mTmpLong = new long[1];
1141
1142     static class ProcessChangeItem {
1143         static final int CHANGE_ACTIVITIES = 1<<0;
1144         static final int CHANGE_PROCESS_STATE = 1<<1;
1145         int changes;
1146         int uid;
1147         int pid;
1148         int processState;
1149         boolean foregroundActivities;
1150     }
1151
1152     final RemoteCallbackList<IProcessObserver> mProcessObservers
1153             = new RemoteCallbackList<IProcessObserver>();
1154     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1155
1156     final ArrayList<ProcessChangeItem> mPendingProcessChanges
1157             = new ArrayList<ProcessChangeItem>();
1158     final ArrayList<ProcessChangeItem> mAvailProcessChanges
1159             = new ArrayList<ProcessChangeItem>();
1160
1161     /**
1162      * Runtime CPU use collection thread.  This object's lock is used to
1163      * perform synchronization with the thread (notifying it to run).
1164      */
1165     final Thread mProcessCpuThread;
1166
1167     /**
1168      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1169      * Must acquire this object's lock when accessing it.
1170      * NOTE: this lock will be held while doing long operations (trawling
1171      * through all processes in /proc), so it should never be acquired by
1172      * any critical paths such as when holding the main activity manager lock.
1173      */
1174     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1175             MONITOR_THREAD_CPU_USAGE);
1176     final AtomicLong mLastCpuTime = new AtomicLong(0);
1177     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1178
1179     long mLastWriteTime = 0;
1180
1181     /**
1182      * Used to retain an update lock when the foreground activity is in
1183      * immersive mode.
1184      */
1185     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1186
1187     /**
1188      * Set to true after the system has finished booting.
1189      */
1190     boolean mBooted = false;
1191
1192     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1193     int mProcessLimitOverride = -1;
1194
1195     WindowManagerService mWindowManager;
1196
1197     final ActivityThread mSystemThread;
1198
1199     // Holds the current foreground user's id
1200     int mCurrentUserId = 0;
1201     // Holds the target user's id during a user switch
1202     int mTargetUserId = UserHandle.USER_NULL;
1203     // If there are multiple profiles for the current user, their ids are here
1204     // Currently only the primary user can have managed profiles
1205     int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1206
1207     /**
1208      * Mapping from each known user ID to the profile group ID it is associated with.
1209      */
1210     SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1211
1212     private UserManagerService mUserManager;
1213
1214     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1215         final ProcessRecord mApp;
1216         final int mPid;
1217         final IApplicationThread mAppThread;
1218
1219         AppDeathRecipient(ProcessRecord app, int pid,
1220                 IApplicationThread thread) {
1221             if (localLOGV) Slog.v(
1222                 TAG, "New death recipient " + this
1223                 + " for thread " + thread.asBinder());
1224             mApp = app;
1225             mPid = pid;
1226             mAppThread = thread;
1227         }
1228
1229         @Override
1230         public void binderDied() {
1231             if (localLOGV) Slog.v(
1232                 TAG, "Death received in " + this
1233                 + " for thread " + mAppThread.asBinder());
1234             synchronized(ActivityManagerService.this) {
1235                 appDiedLocked(mApp, mPid, mAppThread);
1236             }
1237         }
1238     }
1239
1240     static final int SHOW_ERROR_MSG = 1;
1241     static final int SHOW_NOT_RESPONDING_MSG = 2;
1242     static final int SHOW_FACTORY_ERROR_MSG = 3;
1243     static final int UPDATE_CONFIGURATION_MSG = 4;
1244     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1245     static final int WAIT_FOR_DEBUGGER_MSG = 6;
1246     static final int SERVICE_TIMEOUT_MSG = 12;
1247     static final int UPDATE_TIME_ZONE = 13;
1248     static final int SHOW_UID_ERROR_MSG = 14;
1249     static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1250     static final int PROC_START_TIMEOUT_MSG = 20;
1251     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1252     static final int KILL_APPLICATION_MSG = 22;
1253     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1254     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1255     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1256     static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1257     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1258     static final int CLEAR_DNS_CACHE_MSG = 28;
1259     static final int UPDATE_HTTP_PROXY_MSG = 29;
1260     static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1261     static final int DISPATCH_PROCESSES_CHANGED = 31;
1262     static final int DISPATCH_PROCESS_DIED = 32;
1263     static final int REPORT_MEM_USAGE_MSG = 33;
1264     static final int REPORT_USER_SWITCH_MSG = 34;
1265     static final int CONTINUE_USER_SWITCH_MSG = 35;
1266     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1267     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1268     static final int PERSIST_URI_GRANTS_MSG = 38;
1269     static final int REQUEST_ALL_PSS_MSG = 39;
1270     static final int START_PROFILES_MSG = 40;
1271     static final int UPDATE_TIME = 41;
1272     static final int SYSTEM_USER_START_MSG = 42;
1273     static final int SYSTEM_USER_CURRENT_MSG = 43;
1274     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1275     static final int FINISH_BOOTING_MSG = 45;
1276     static final int START_USER_SWITCH_MSG = 46;
1277     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1278     static final int DISMISS_DIALOG_MSG = 48;
1279     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1280
1281     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1282     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1283     static final int FIRST_COMPAT_MODE_MSG = 300;
1284     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1285
1286     CompatModeDialog mCompatModeDialog;
1287     long mLastMemUsageReportTime = 0;
1288
1289     /**
1290      * Flag whether the current user is a "monkey", i.e. whether
1291      * the UI is driven by a UI automation tool.
1292      */
1293     private boolean mUserIsMonkey;
1294
1295     /** Flag whether the device has a Recents UI */
1296     boolean mHasRecents;
1297
1298     /** The dimensions of the thumbnails in the Recents UI. */
1299     int mThumbnailWidth;
1300     int mThumbnailHeight;
1301
1302     final ServiceThread mHandlerThread;
1303     final MainHandler mHandler;
1304
1305     final class MainHandler extends Handler {
1306         public MainHandler(Looper looper) {
1307             super(looper, null, true);
1308         }
1309
1310         @Override
1311         public void handleMessage(Message msg) {
1312             switch (msg.what) {
1313             case SHOW_ERROR_MSG: {
1314                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1315                 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1316                         Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1317                 synchronized (ActivityManagerService.this) {
1318                     ProcessRecord proc = (ProcessRecord)data.get("app");
1319                     AppErrorResult res = (AppErrorResult) data.get("result");
1320                     if (proc != null && proc.crashDialog != null) {
1321                         Slog.e(TAG, "App already has crash dialog: " + proc);
1322                         if (res != null) {
1323                             res.set(0);
1324                         }
1325                         return;
1326                     }
1327                     boolean isBackground = (UserHandle.getAppId(proc.uid)
1328                             >= Process.FIRST_APPLICATION_UID
1329                             && proc.pid != MY_PID);
1330                     for (int userId : mCurrentProfileIds) {
1331                         isBackground &= (proc.userId != userId);
1332                     }
1333                     if (isBackground && !showBackground) {
1334                         Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1335                         if (res != null) {
1336                             res.set(0);
1337                         }
1338                         return;
1339                     }
1340                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1341                         Dialog d = new AppErrorDialog(mContext,
1342                                 ActivityManagerService.this, res, proc);
1343                         d.show();
1344                         proc.crashDialog = d;
1345                     } else {
1346                         // The device is asleep, so just pretend that the user
1347                         // saw a crash dialog and hit "force quit".
1348                         if (res != null) {
1349                             res.set(0);
1350                         }
1351                     }
1352                 }
1353
1354                 ensureBootCompleted();
1355             } break;
1356             case SHOW_NOT_RESPONDING_MSG: {
1357                 synchronized (ActivityManagerService.this) {
1358                     HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1359                     ProcessRecord proc = (ProcessRecord)data.get("app");
1360                     if (proc != null && proc.anrDialog != null) {
1361                         Slog.e(TAG, "App already has anr dialog: " + proc);
1362                         return;
1363                     }
1364
1365                     Intent intent = new Intent("android.intent.action.ANR");
1366                     if (!mProcessesReady) {
1367                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1368                                 | Intent.FLAG_RECEIVER_FOREGROUND);
1369                     }
1370                     broadcastIntentLocked(null, null, intent,
1371                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1372                             false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1373
1374                     if (mShowDialogs) {
1375                         Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1376                                 mContext, proc, (ActivityRecord)data.get("activity"),
1377                                 msg.arg1 != 0);
1378                         d.show();
1379                         proc.anrDialog = d;
1380                     } else {
1381                         // Just kill the app if there is no dialog to be shown.
1382                         killAppAtUsersRequest(proc, null);
1383                     }
1384                 }
1385
1386                 ensureBootCompleted();
1387             } break;
1388             case SHOW_STRICT_MODE_VIOLATION_MSG: {
1389                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1390                 synchronized (ActivityManagerService.this) {
1391                     ProcessRecord proc = (ProcessRecord) data.get("app");
1392                     if (proc == null) {
1393                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1394                         break;
1395                     }
1396                     if (proc.crashDialog != null) {
1397                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1398                         return;
1399                     }
1400                     AppErrorResult res = (AppErrorResult) data.get("result");
1401                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1402                         Dialog d = new StrictModeViolationDialog(mContext,
1403                                 ActivityManagerService.this, res, proc);
1404                         d.show();
1405                         proc.crashDialog = d;
1406                     } else {
1407                         // The device is asleep, so just pretend that the user
1408                         // saw a crash dialog and hit "force quit".
1409                         res.set(0);
1410                     }
1411                 }
1412                 ensureBootCompleted();
1413             } break;
1414             case SHOW_FACTORY_ERROR_MSG: {
1415                 Dialog d = new FactoryErrorDialog(
1416                     mContext, msg.getData().getCharSequence("msg"));
1417                 d.show();
1418                 ensureBootCompleted();
1419             } break;
1420             case UPDATE_CONFIGURATION_MSG: {
1421                 final ContentResolver resolver = mContext.getContentResolver();
1422                 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1423             } break;
1424             case GC_BACKGROUND_PROCESSES_MSG: {
1425                 synchronized (ActivityManagerService.this) {
1426                     performAppGcsIfAppropriateLocked();
1427                 }
1428             } break;
1429             case WAIT_FOR_DEBUGGER_MSG: {
1430                 synchronized (ActivityManagerService.this) {
1431                     ProcessRecord app = (ProcessRecord)msg.obj;
1432                     if (msg.arg1 != 0) {
1433                         if (!app.waitedForDebugger) {
1434                             Dialog d = new AppWaitingForDebuggerDialog(
1435                                     ActivityManagerService.this,
1436                                     mContext, app);
1437                             app.waitDialog = d;
1438                             app.waitedForDebugger = true;
1439                             d.show();
1440                         }
1441                     } else {
1442                         if (app.waitDialog != null) {
1443                             app.waitDialog.dismiss();
1444                             app.waitDialog = null;
1445                         }
1446                     }
1447                 }
1448             } break;
1449             case SERVICE_TIMEOUT_MSG: {
1450                 if (mDidDexOpt) {
1451                     mDidDexOpt = false;
1452                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1453                     nmsg.obj = msg.obj;
1454                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1455                     return;
1456                 }
1457                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1458             } break;
1459             case UPDATE_TIME_ZONE: {
1460                 synchronized (ActivityManagerService.this) {
1461                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462                         ProcessRecord r = mLruProcesses.get(i);
1463                         if (r.thread != null) {
1464                             try {
1465                                 r.thread.updateTimeZone();
1466                             } catch (RemoteException ex) {
1467                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1468                             }
1469                         }
1470                     }
1471                 }
1472             } break;
1473             case CLEAR_DNS_CACHE_MSG: {
1474                 synchronized (ActivityManagerService.this) {
1475                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1476                         ProcessRecord r = mLruProcesses.get(i);
1477                         if (r.thread != null) {
1478                             try {
1479                                 r.thread.clearDnsCache();
1480                             } catch (RemoteException ex) {
1481                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1482                             }
1483                         }
1484                     }
1485                 }
1486             } break;
1487             case UPDATE_HTTP_PROXY_MSG: {
1488                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1489                 String host = "";
1490                 String port = "";
1491                 String exclList = "";
1492                 Uri pacFileUrl = Uri.EMPTY;
1493                 if (proxy != null) {
1494                     host = proxy.getHost();
1495                     port = Integer.toString(proxy.getPort());
1496                     exclList = proxy.getExclusionListAsString();
1497                     pacFileUrl = proxy.getPacFileUrl();
1498                 }
1499                 synchronized (ActivityManagerService.this) {
1500                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1501                         ProcessRecord r = mLruProcesses.get(i);
1502                         if (r.thread != null) {
1503                             try {
1504                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1505                             } catch (RemoteException ex) {
1506                                 Slog.w(TAG, "Failed to update http proxy for: " +
1507                                         r.info.processName);
1508                             }
1509                         }
1510                     }
1511                 }
1512             } break;
1513             case SHOW_UID_ERROR_MSG: {
1514                 if (mShowDialogs) {
1515                     AlertDialog d = new BaseErrorDialog(mContext);
1516                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1517                     d.setCancelable(false);
1518                     d.setTitle(mContext.getText(R.string.android_system_label));
1519                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1520                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1521                             mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1522                     d.show();
1523                 }
1524             } break;
1525             case SHOW_FINGERPRINT_ERROR_MSG: {
1526                 if (mShowDialogs) {
1527                     AlertDialog d = new BaseErrorDialog(mContext);
1528                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1529                     d.setCancelable(false);
1530                     d.setTitle(mContext.getText(R.string.android_system_label));
1531                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1532                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1533                             mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1534                     d.show();
1535                 }
1536             } break;
1537             case PROC_START_TIMEOUT_MSG: {
1538                 if (mDidDexOpt) {
1539                     mDidDexOpt = false;
1540                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1541                     nmsg.obj = msg.obj;
1542                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1543                     return;
1544                 }
1545                 ProcessRecord app = (ProcessRecord)msg.obj;
1546                 synchronized (ActivityManagerService.this) {
1547                     processStartTimedOutLocked(app);
1548                 }
1549             } break;
1550             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1551                 synchronized (ActivityManagerService.this) {
1552                     mStackSupervisor.doPendingActivityLaunchesLocked(true);
1553                 }
1554             } break;
1555             case KILL_APPLICATION_MSG: {
1556                 synchronized (ActivityManagerService.this) {
1557                     int appid = msg.arg1;
1558                     boolean restart = (msg.arg2 == 1);
1559                     Bundle bundle = (Bundle)msg.obj;
1560                     String pkg = bundle.getString("pkg");
1561                     String reason = bundle.getString("reason");
1562                     forceStopPackageLocked(pkg, appid, restart, false, true, false,
1563                             false, UserHandle.USER_ALL, reason);
1564                 }
1565             } break;
1566             case FINALIZE_PENDING_INTENT_MSG: {
1567                 ((PendingIntentRecord)msg.obj).completeFinalize();
1568             } break;
1569             case POST_HEAVY_NOTIFICATION_MSG: {
1570                 INotificationManager inm = NotificationManager.getService();
1571                 if (inm == null) {
1572                     return;
1573                 }
1574
1575                 ActivityRecord root = (ActivityRecord)msg.obj;
1576                 ProcessRecord process = root.app;
1577                 if (process == null) {
1578                     return;
1579                 }
1580
1581                 try {
1582                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1583                     String text = mContext.getString(R.string.heavy_weight_notification,
1584                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1585                     Notification notification = new Notification();
1586                     notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1587                     notification.when = 0;
1588                     notification.flags = Notification.FLAG_ONGOING_EVENT;
1589                     notification.tickerText = text;
1590                     notification.defaults = 0; // please be quiet
1591                     notification.sound = null;
1592                     notification.vibrate = null;
1593                     notification.color = mContext.getResources().getColor(
1594                             com.android.internal.R.color.system_notification_accent_color);
1595                     notification.setLatestEventInfo(context, text,
1596                             mContext.getText(R.string.heavy_weight_notification_detail),
1597                             PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1598                                     PendingIntent.FLAG_CANCEL_CURRENT, null,
1599                                     new UserHandle(root.userId)));
1600
1601                     try {
1602                         int[] outId = new int[1];
1603                         inm.enqueueNotificationWithTag("android", "android", null,
1604                                 R.string.heavy_weight_notification,
1605                                 notification, outId, root.userId);
1606                     } catch (RuntimeException e) {
1607                         Slog.w(ActivityManagerService.TAG,
1608                                 "Error showing notification for heavy-weight app", e);
1609                     } catch (RemoteException e) {
1610                     }
1611                 } catch (NameNotFoundException e) {
1612                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1613                 }
1614             } break;
1615             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1616                 INotificationManager inm = NotificationManager.getService();
1617                 if (inm == null) {
1618                     return;
1619                 }
1620                 try {
1621                     inm.cancelNotificationWithTag("android", null,
1622                             R.string.heavy_weight_notification,  msg.arg1);
1623                 } catch (RuntimeException e) {
1624                     Slog.w(ActivityManagerService.TAG,
1625                             "Error canceling notification for service", e);
1626                 } catch (RemoteException e) {
1627                 }
1628             } break;
1629             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1630                 synchronized (ActivityManagerService.this) {
1631                     checkExcessivePowerUsageLocked(true);
1632                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1633                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1634                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1635                 }
1636             } break;
1637             case SHOW_COMPAT_MODE_DIALOG_MSG: {
1638                 synchronized (ActivityManagerService.this) {
1639                     ActivityRecord ar = (ActivityRecord)msg.obj;
1640                     if (mCompatModeDialog != null) {
1641                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1642                                 ar.info.applicationInfo.packageName)) {
1643                             return;
1644                         }
1645                         mCompatModeDialog.dismiss();
1646                         mCompatModeDialog = null;
1647                     }
1648                     if (ar != null && false) {
1649                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1650                                 ar.packageName)) {
1651                             int mode = mCompatModePackages.computeCompatModeLocked(
1652                                     ar.info.applicationInfo);
1653                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655                                 mCompatModeDialog = new CompatModeDialog(
1656                                         ActivityManagerService.this, mContext,
1657                                         ar.info.applicationInfo);
1658                                 mCompatModeDialog.show();
1659                             }
1660                         }
1661                     }
1662                 }
1663                 break;
1664             }
1665             case DISPATCH_PROCESSES_CHANGED: {
1666                 dispatchProcessesChanged();
1667                 break;
1668             }
1669             case DISPATCH_PROCESS_DIED: {
1670                 final int pid = msg.arg1;
1671                 final int uid = msg.arg2;
1672                 dispatchProcessDied(pid, uid);
1673                 break;
1674             }
1675             case REPORT_MEM_USAGE_MSG: {
1676                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1677                 Thread thread = new Thread() {
1678                     @Override public void run() {
1679                         reportMemUsage(memInfos);
1680                     }
1681                 };
1682                 thread.start();
1683                 break;
1684             }
1685             case START_USER_SWITCH_MSG: {
1686                 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1687                 break;
1688             }
1689             case REPORT_USER_SWITCH_MSG: {
1690                 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1691                 break;
1692             }
1693             case CONTINUE_USER_SWITCH_MSG: {
1694                 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1695                 break;
1696             }
1697             case USER_SWITCH_TIMEOUT_MSG: {
1698                 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1699                 break;
1700             }
1701             case IMMERSIVE_MODE_LOCK_MSG: {
1702                 final boolean nextState = (msg.arg1 != 0);
1703                 if (mUpdateLock.isHeld() != nextState) {
1704                     if (DEBUG_IMMERSIVE) {
1705                         final ActivityRecord r = (ActivityRecord) msg.obj;
1706                         Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1707                     }
1708                     if (nextState) {
1709                         mUpdateLock.acquire();
1710                     } else {
1711                         mUpdateLock.release();
1712                     }
1713                 }
1714                 break;
1715             }
1716             case PERSIST_URI_GRANTS_MSG: {
1717                 writeGrantedUriPermissions();
1718                 break;
1719             }
1720             case REQUEST_ALL_PSS_MSG: {
1721                 synchronized (ActivityManagerService.this) {
1722                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1723                 }
1724                 break;
1725             }
1726             case START_PROFILES_MSG: {
1727                 synchronized (ActivityManagerService.this) {
1728                     startProfilesLocked();
1729                 }
1730                 break;
1731             }
1732             case UPDATE_TIME: {
1733                 synchronized (ActivityManagerService.this) {
1734                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1735                         ProcessRecord r = mLruProcesses.get(i);
1736                         if (r.thread != null) {
1737                             try {
1738                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1739                             } catch (RemoteException ex) {
1740                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1741                             }
1742                         }
1743                     }
1744                 }
1745                 break;
1746             }
1747             case SYSTEM_USER_START_MSG: {
1748                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1749                         Integer.toString(msg.arg1), msg.arg1);
1750                 mSystemServiceManager.startUser(msg.arg1);
1751                 break;
1752             }
1753             case SYSTEM_USER_CURRENT_MSG: {
1754                 mBatteryStatsService.noteEvent(
1755                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1756                         Integer.toString(msg.arg2), msg.arg2);
1757                 mBatteryStatsService.noteEvent(
1758                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1759                         Integer.toString(msg.arg1), msg.arg1);
1760                 mSystemServiceManager.switchUser(msg.arg1);
1761                 break;
1762             }
1763             case ENTER_ANIMATION_COMPLETE_MSG: {
1764                 synchronized (ActivityManagerService.this) {
1765                     ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1766                     if (r != null && r.app != null && r.app.thread != null) {
1767                         try {
1768                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1769                         } catch (RemoteException e) {
1770                         }
1771                     }
1772                 }
1773                 break;
1774             }
1775             case FINISH_BOOTING_MSG: {
1776                 if (msg.arg1 != 0) {
1777                     finishBooting();
1778                 }
1779                 if (msg.arg2 != 0) {
1780                     enableScreenAfterBoot();
1781                 }
1782                 break;
1783             }
1784             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1785                 try {
1786                     Locale l = (Locale) msg.obj;
1787                     IBinder service = ServiceManager.getService("mount");
1788                     IMountService mountService = IMountService.Stub.asInterface(service);
1789                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1790                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1791                 } catch (RemoteException e) {
1792                     Log.e(TAG, "Error storing locale for decryption UI", e);
1793                 }
1794                 break;
1795             }
1796             case DISMISS_DIALOG_MSG: {
1797                 final Dialog d = (Dialog) msg.obj;
1798                 d.dismiss();
1799                 break;
1800             }
1801             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1802                 synchronized (ActivityManagerService.this) {
1803                     int i = mTaskStackListeners.beginBroadcast();
1804                     while (i > 0) {
1805                         i--;
1806                         try {
1807                             // Make a one-way callback to the listener
1808                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1809                         } catch (RemoteException e){
1810                             // Handled by the RemoteCallbackList
1811                         }
1812                     }
1813                     mTaskStackListeners.finishBroadcast();
1814                 }
1815                 break;
1816             }
1817             }
1818         }
1819     };
1820
1821     static final int COLLECT_PSS_BG_MSG = 1;
1822
1823     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1824         @Override
1825         public void handleMessage(Message msg) {
1826             switch (msg.what) {
1827             case COLLECT_PSS_BG_MSG: {
1828                 long start = SystemClock.uptimeMillis();
1829                 MemInfoReader memInfo = null;
1830                 synchronized (ActivityManagerService.this) {
1831                     if (mFullPssPending) {
1832                         mFullPssPending = false;
1833                         memInfo = new MemInfoReader();
1834                     }
1835                 }
1836                 if (memInfo != null) {
1837                     updateCpuStatsNow();
1838                     long nativeTotalPss = 0;
1839                     synchronized (mProcessCpuTracker) {
1840                         final int N = mProcessCpuTracker.countStats();
1841                         for (int j=0; j<N; j++) {
1842                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1843                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1844                                 // This is definitely an application process; skip it.
1845                                 continue;
1846                             }
1847                             synchronized (mPidsSelfLocked) {
1848                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1849                                     // This is one of our own processes; skip it.
1850                                     continue;
1851                                 }
1852                             }
1853                             nativeTotalPss += Debug.getPss(st.pid, null, null);
1854                         }
1855                     }
1856                     memInfo.readMemInfo();
1857                     synchronized (ActivityManagerService.this) {
1858                         if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1859                                 + (SystemClock.uptimeMillis()-start) + "ms");
1860                         mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1861                                 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1862                                 memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1863                     }
1864                 }
1865
1866                 int num = 0;
1867                 long[] tmp = new long[1];
1868                 do {
1869                     ProcessRecord proc;
1870                     int procState;
1871                     int pid;
1872                     long lastPssTime;
1873                     synchronized (ActivityManagerService.this) {
1874                         if (mPendingPssProcesses.size() <= 0) {
1875                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1876                                     + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1877                             mPendingPssProcesses.clear();
1878                             return;
1879                         }
1880                         proc = mPendingPssProcesses.remove(0);
1881                         procState = proc.pssProcState;
1882                         lastPssTime = proc.lastPssTime;
1883                         if (proc.thread != null && procState == proc.setProcState
1884                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1885                                         < SystemClock.uptimeMillis()) {
1886                             pid = proc.pid;
1887                         } else {
1888                             proc = null;
1889                             pid = 0;
1890                         }
1891                     }
1892                     if (proc != null) {
1893                         long pss = Debug.getPss(pid, tmp, null);
1894                         synchronized (ActivityManagerService.this) {
1895                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
1896                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1897                                 num++;
1898                                 recordPssSample(proc, procState, pss, tmp[0],
1899                                         SystemClock.uptimeMillis());
1900                             }
1901                         }
1902                     }
1903                 } while (true);
1904             }
1905             }
1906         }
1907     };
1908
1909     public void setSystemProcess() {
1910         try {
1911             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1912             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1913             ServiceManager.addService("meminfo", new MemBinder(this));
1914             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1915             ServiceManager.addService("dbinfo", new DbBinder(this));
1916             if (MONITOR_CPU_USAGE) {
1917                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
1918             }
1919             ServiceManager.addService("permission", new PermissionController(this));
1920
1921             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1922                     "android", STOCK_PM_FLAGS);
1923             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1924
1925             synchronized (this) {
1926                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1927                 app.persistent = true;
1928                 app.pid = MY_PID;
1929                 app.maxAdj = ProcessList.SYSTEM_ADJ;
1930                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1931                 mProcessNames.put(app.processName, app.uid, app);
1932                 synchronized (mPidsSelfLocked) {
1933                     mPidsSelfLocked.put(app.pid, app);
1934                 }
1935                 updateLruProcessLocked(app, false, null);
1936                 updateOomAdjLocked();
1937             }
1938         } catch (PackageManager.NameNotFoundException e) {
1939             throw new RuntimeException(
1940                     "Unable to find android system package", e);
1941         }
1942     }
1943
1944     public void setWindowManager(WindowManagerService wm) {
1945         mWindowManager = wm;
1946         mStackSupervisor.setWindowManager(wm);
1947     }
1948
1949     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1950         mUsageStatsService = usageStatsManager;
1951     }
1952
1953     public void startObservingNativeCrashes() {
1954         final NativeCrashListener ncl = new NativeCrashListener(this);
1955         ncl.start();
1956     }
1957
1958     public IAppOpsService getAppOpsService() {
1959         return mAppOpsService;
1960     }
1961
1962     static class MemBinder extends Binder {
1963         ActivityManagerService mActivityManagerService;
1964         MemBinder(ActivityManagerService activityManagerService) {
1965             mActivityManagerService = activityManagerService;
1966         }
1967
1968         @Override
1969         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1970             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1971                     != PackageManager.PERMISSION_GRANTED) {
1972                 pw.println("Permission Denial: can't dump meminfo from from pid="
1973                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1974                         + " without permission " + android.Manifest.permission.DUMP);
1975                 return;
1976             }
1977
1978             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
1979         }
1980     }
1981
1982     static class GraphicsBinder extends Binder {
1983         ActivityManagerService mActivityManagerService;
1984         GraphicsBinder(ActivityManagerService activityManagerService) {
1985             mActivityManagerService = activityManagerService;
1986         }
1987
1988         @Override
1989         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1990             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1991                     != PackageManager.PERMISSION_GRANTED) {
1992                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1993                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1994                         + " without permission " + android.Manifest.permission.DUMP);
1995                 return;
1996             }
1997
1998             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1999         }
2000     }
2001
2002     static class DbBinder extends Binder {
2003         ActivityManagerService mActivityManagerService;
2004         DbBinder(ActivityManagerService activityManagerService) {
2005             mActivityManagerService = activityManagerService;
2006         }
2007
2008         @Override
2009         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2010             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2011                     != PackageManager.PERMISSION_GRANTED) {
2012                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2013                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2014                         + " without permission " + android.Manifest.permission.DUMP);
2015                 return;
2016             }
2017
2018             mActivityManagerService.dumpDbInfo(fd, pw, args);
2019         }
2020     }
2021
2022     static class CpuBinder extends Binder {
2023         ActivityManagerService mActivityManagerService;
2024         CpuBinder(ActivityManagerService activityManagerService) {
2025             mActivityManagerService = activityManagerService;
2026         }
2027
2028         @Override
2029         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2030             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2031                     != PackageManager.PERMISSION_GRANTED) {
2032                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2033                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2034                         + " without permission " + android.Manifest.permission.DUMP);
2035                 return;
2036             }
2037
2038             synchronized (mActivityManagerService.mProcessCpuTracker) {
2039                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2040                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2041                         SystemClock.uptimeMillis()));
2042             }
2043         }
2044     }
2045
2046     public static final class Lifecycle extends SystemService {
2047         private final ActivityManagerService mService;
2048
2049         public Lifecycle(Context context) {
2050             super(context);
2051             mService = new ActivityManagerService(context);
2052         }
2053
2054         @Override
2055         public void onStart() {
2056             mService.start();
2057         }
2058
2059         public ActivityManagerService getService() {
2060             return mService;
2061         }
2062     }
2063
2064     // Note: This method is invoked on the main thread but may need to attach various
2065     // handlers to other threads.  So take care to be explicit about the looper.
2066     public ActivityManagerService(Context systemContext) {
2067         mContext = systemContext;
2068         mFactoryTest = FactoryTest.getMode();
2069         mSystemThread = ActivityThread.currentActivityThread();
2070
2071         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2072
2073         mHandlerThread = new ServiceThread(TAG,
2074                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2075         mHandlerThread.start();
2076         mHandler = new MainHandler(mHandlerThread.getLooper());
2077
2078         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2079                 "foreground", BROADCAST_FG_TIMEOUT, false);
2080         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2081                 "background", BROADCAST_BG_TIMEOUT, true);
2082         mBroadcastQueues[0] = mFgBroadcastQueue;
2083         mBroadcastQueues[1] = mBgBroadcastQueue;
2084
2085         mServices = new ActiveServices(this);
2086         mProviderMap = new ProviderMap(this);
2087
2088         // TODO: Move creation of battery stats service outside of activity manager service.
2089         File dataDir = Environment.getDataDirectory();
2090         File systemDir = new File(dataDir, "system");
2091         systemDir.mkdirs();
2092         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2093         mBatteryStatsService.getActiveStatistics().readLocked();
2094         mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2095         mOnBattery = DEBUG_POWER ? true
2096                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2097         mBatteryStatsService.getActiveStatistics().setCallback(this);
2098
2099         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2100
2101         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2102
2103         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2104
2105         // User 0 is the first and only user that runs at boot.
2106         mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2107         mUserLru.add(Integer.valueOf(0));
2108         updateStartedUserArrayLocked();
2109
2110         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2111             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2112
2113         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2114
2115         mConfiguration.setToDefaults();
2116         mConfiguration.locale = Locale.getDefault();
2117
2118         mConfigurationSeq = mConfiguration.seq = 1;
2119         mProcessCpuTracker.init();
2120
2121         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2122         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2123         mStackSupervisor = new ActivityStackSupervisor(this);
2124         mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2125
2126         mProcessCpuThread = new Thread("CpuTracker") {
2127             @Override
2128             public void run() {
2129                 while (true) {
2130                     try {
2131                         try {
2132                             synchronized(this) {
2133                                 final long now = SystemClock.uptimeMillis();
2134                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2135                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2136                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2137                                 //        + ", write delay=" + nextWriteDelay);
2138                                 if (nextWriteDelay < nextCpuDelay) {
2139                                     nextCpuDelay = nextWriteDelay;
2140                                 }
2141                                 if (nextCpuDelay > 0) {
2142                                     mProcessCpuMutexFree.set(true);
2143                                     this.wait(nextCpuDelay);
2144                                 }
2145                             }
2146                         } catch (InterruptedException e) {
2147                         }
2148                         updateCpuStatsNow();
2149                     } catch (Exception e) {
2150                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2151                     }
2152                 }
2153             }
2154         };
2155
2156         Watchdog.getInstance().addMonitor(this);
2157         Watchdog.getInstance().addThread(mHandler);
2158     }
2159
2160     public void setSystemServiceManager(SystemServiceManager mgr) {
2161         mSystemServiceManager = mgr;
2162     }
2163
2164     public void setInstaller(Installer installer) {
2165         mInstaller = installer;
2166     }
2167
2168     private void start() {
2169         Process.removeAllProcessGroups();
2170         mProcessCpuThread.start();
2171
2172         mBatteryStatsService.publish(mContext);
2173         mAppOpsService.publish(mContext);
2174         Slog.d("AppOps", "AppOpsService published");
2175         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2176     }
2177
2178     public void initPowerManagement() {
2179         mStackSupervisor.initPowerManagement();
2180         mBatteryStatsService.initPowerManagement();
2181     }
2182
2183     @Override
2184     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2185             throws RemoteException {
2186         if (code == SYSPROPS_TRANSACTION) {
2187             // We need to tell all apps about the system property change.
2188             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2189             synchronized(this) {
2190                 final int NP = mProcessNames.getMap().size();
2191                 for (int ip=0; ip<NP; ip++) {
2192                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2193                     final int NA = apps.size();
2194                     for (int ia=0; ia<NA; ia++) {
2195                         ProcessRecord app = apps.valueAt(ia);
2196                         if (app.thread != null) {
2197                             procs.add(app.thread.asBinder());
2198                         }
2199                     }
2200                 }
2201             }
2202
2203             int N = procs.size();
2204             for (int i=0; i<N; i++) {
2205                 Parcel data2 = Parcel.obtain();
2206                 try {
2207                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2208                 } catch (RemoteException e) {
2209                 }
2210                 data2.recycle();
2211             }
2212         }
2213         try {
2214             return super.onTransact(code, data, reply, flags);
2215         } catch (RuntimeException e) {
2216             // The activity manager only throws security exceptions, so let's
2217             // log all others.
2218             if (!(e instanceof SecurityException)) {
2219                 Slog.wtf(TAG, "Activity Manager Crash", e);
2220             }
2221             throw e;
2222         }
2223     }
2224
2225     void updateCpuStats() {
2226         final long now = SystemClock.uptimeMillis();
2227         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2228             return;
2229         }
2230         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2231             synchronized (mProcessCpuThread) {
2232                 mProcessCpuThread.notify();
2233             }
2234         }
2235     }
2236
2237     void updateCpuStatsNow() {
2238         synchronized (mProcessCpuTracker) {
2239             mProcessCpuMutexFree.set(false);
2240             final long now = SystemClock.uptimeMillis();
2241             boolean haveNewCpuStats = false;
2242
2243             if (MONITOR_CPU_USAGE &&
2244                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2245                 mLastCpuTime.set(now);
2246                 haveNewCpuStats = true;
2247                 mProcessCpuTracker.update();
2248                 //Slog.i(TAG, mProcessCpu.printCurrentState());
2249                 //Slog.i(TAG, "Total CPU usage: "
2250                 //        + mProcessCpu.getTotalCpuPercent() + "%");
2251
2252                 // Slog the cpu usage if the property is set.
2253                 if ("true".equals(SystemProperties.get("events.cpu"))) {
2254                     int user = mProcessCpuTracker.getLastUserTime();
2255                     int system = mProcessCpuTracker.getLastSystemTime();
2256                     int iowait = mProcessCpuTracker.getLastIoWaitTime();
2257                     int irq = mProcessCpuTracker.getLastIrqTime();
2258                     int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2259                     int idle = mProcessCpuTracker.getLastIdleTime();
2260
2261                     int total = user + system + iowait + irq + softIrq + idle;
2262                     if (total == 0) total = 1;
2263
2264                     EventLog.writeEvent(EventLogTags.CPU,
2265                             ((user+system+iowait+irq+softIrq) * 100) / total,
2266                             (user * 100) / total,
2267                             (system * 100) / total,
2268                             (iowait * 100) / total,
2269                             (irq * 100) / total,
2270                             (softIrq * 100) / total);
2271                 }
2272             }
2273
2274             long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2275             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2276             synchronized(bstats) {
2277                 synchronized(mPidsSelfLocked) {
2278                     if (haveNewCpuStats) {
2279                         if (mOnBattery) {
2280                             int perc = bstats.startAddingCpuLocked();
2281                             int totalUTime = 0;
2282                             int totalSTime = 0;
2283                             final int N = mProcessCpuTracker.countStats();
2284                             for (int i=0; i<N; i++) {
2285                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2286                                 if (!st.working) {
2287                                     continue;
2288                                 }
2289                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2290                                 int otherUTime = (st.rel_utime*perc)/100;
2291                                 int otherSTime = (st.rel_stime*perc)/100;
2292                                 totalUTime += otherUTime;
2293                                 totalSTime += otherSTime;
2294                                 if (pr != null) {
2295                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2296                                     if (ps == null || !ps.isActive()) {
2297                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2298                                                 pr.info.uid, pr.processName);
2299                                     }
2300                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2301                                             st.rel_stime-otherSTime);
2302                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2303                                     pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2304                                 } else {
2305                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2306                                     if (ps == null || !ps.isActive()) {
2307                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2308                                                 bstats.mapUid(st.uid), st.name);
2309                                     }
2310                                     ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2311                                             st.rel_stime-otherSTime);
2312                                     ps.addSpeedStepTimes(cpuSpeedTimes);
2313                                 }
2314                             }
2315                             bstats.finishAddingCpuLocked(perc, totalUTime,
2316                                     totalSTime, cpuSpeedTimes);
2317                         }
2318                     }
2319                 }
2320
2321                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2322                     mLastWriteTime = now;
2323                     mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2324                 }
2325             }
2326         }
2327     }
2328
2329     @Override
2330     public void batteryNeedsCpuUpdate() {
2331         updateCpuStatsNow();
2332     }
2333
2334     @Override
2335     public void batteryPowerChanged(boolean onBattery) {
2336         // When plugging in, update the CPU stats first before changing
2337         // the plug state.
2338         updateCpuStatsNow();
2339         synchronized (this) {
2340             synchronized(mPidsSelfLocked) {
2341                 mOnBattery = DEBUG_POWER ? true : onBattery;
2342             }
2343         }
2344     }
2345
2346     /**
2347      * Initialize the application bind args. These are passed to each
2348      * process when the bindApplication() IPC is sent to the process. They're
2349      * lazily setup to make sure the services are running when they're asked for.
2350      */
2351     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2352         // Isolated processes won't get this optimization, so that we don't
2353         // violate the rules about which services they have access to.
2354         if (isolated) {
2355             if (mIsolatedAppBindArgs == null) {
2356                 mIsolatedAppBindArgs = new HashMap<>();
2357                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2358             }
2359             return mIsolatedAppBindArgs;
2360         }
2361
2362         if (mAppBindArgs == null) {
2363             mAppBindArgs = new HashMap<>();
2364
2365             // Setup the application init args
2366             mAppBindArgs.put("package", ServiceManager.getService("package"));
2367             mAppBindArgs.put("window", ServiceManager.getService("window"));
2368             mAppBindArgs.put(Context.ALARM_SERVICE,
2369                     ServiceManager.getService(Context.ALARM_SERVICE));
2370         }
2371         return mAppBindArgs;
2372     }
2373
2374     final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2375         if (mFocusedActivity != r) {
2376             if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2377             mFocusedActivity = r;
2378             if (r.task != null && r.task.voiceInteractor != null) {
2379                 startRunningVoiceLocked();
2380             } else {
2381                 finishRunningVoiceLocked();
2382             }
2383             mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2384             if (r != null) {
2385                 mWindowManager.setFocusedApp(r.appToken, true);
2386             }
2387             applyUpdateLockStateLocked(r);
2388         }
2389         EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2390                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2391     }
2392
2393     final void clearFocusedActivity(ActivityRecord r) {
2394         if (mFocusedActivity == r) {
2395             mFocusedActivity = null;
2396         }
2397     }
2398
2399     @Override
2400     public void setFocusedStack(int stackId) {
2401         if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2402         synchronized (ActivityManagerService.this) {
2403             ActivityStack stack = mStackSupervisor.getStack(stackId);
2404             if (stack != null) {
2405                 ActivityRecord r = stack.topRunningActivityLocked(null);
2406                 if (r != null) {
2407                     setFocusedActivityLocked(r, "setFocusedStack");
2408                 }
2409             }
2410         }
2411     }
2412
2413     /** Sets the task stack listener that gets callbacks when a task stack changes. */
2414     @Override
2415     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2416         synchronized (ActivityManagerService.this) {
2417             if (listener != null) {
2418                 mTaskStackListeners.register(listener);
2419             }
2420         }
2421     }
2422
2423     @Override
2424     public void notifyActivityDrawn(IBinder token) {
2425         if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2426         synchronized (this) {
2427             ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2428             if (r != null) {
2429                 r.task.stack.notifyActivityDrawnLocked(r);
2430             }
2431         }
2432     }
2433
2434     final void applyUpdateLockStateLocked(ActivityRecord r) {
2435         // Modifications to the UpdateLock state are done on our handler, outside
2436         // the activity manager's locks.  The new state is determined based on the
2437         // state *now* of the relevant activity record.  The object is passed to
2438         // the handler solely for logging detail, not to be consulted/modified.
2439         final boolean nextState = r != null && r.immersive;
2440         mHandler.sendMessage(
2441                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2442     }
2443
2444     final void showAskCompatModeDialogLocked(ActivityRecord r) {
2445         Message msg = Message.obtain();
2446         msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2447         msg.obj = r.task.askedCompatMode ? null : r;
2448         mHandler.sendMessage(msg);
2449     }
2450
2451     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2452             String what, Object obj, ProcessRecord srcApp) {
2453         app.lastActivityTime = now;
2454
2455         if (app.activities.size() > 0) {
2456             // Don't want to touch dependent processes that are hosting activities.
2457             return index;
2458         }
2459
2460         int lrui = mLruProcesses.lastIndexOf(app);
2461         if (lrui < 0) {
2462             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2463                     + what + " " + obj + " from " + srcApp);
2464             return index;
2465         }
2466
2467         if (lrui >= index) {
2468             // Don't want to cause this to move dependent processes *back* in the
2469             // list as if they were less frequently used.
2470             return index;
2471         }
2472
2473         if (lrui >= mLruProcessActivityStart) {
2474             // Don't want to touch dependent processes that are hosting activities.
2475             return index;
2476         }
2477
2478         mLruProcesses.remove(lrui);
2479         if (index > 0) {
2480             index--;
2481         }
2482         if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2483                 + " in LRU list: " + app);
2484         mLruProcesses.add(index, app);
2485         return index;
2486     }
2487
2488     final void removeLruProcessLocked(ProcessRecord app) {
2489         int lrui = mLruProcesses.lastIndexOf(app);
2490         if (lrui >= 0) {
2491             if (!app.killed) {
2492                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2493                 Process.killProcessQuiet(app.pid);
2494                 Process.killProcessGroup(app.uid, app.pid);
2495             }
2496             if (lrui <= mLruProcessActivityStart) {
2497                 mLruProcessActivityStart--;
2498             }
2499             if (lrui <= mLruProcessServiceStart) {
2500                 mLruProcessServiceStart--;
2501             }
2502             mLruProcesses.remove(lrui);
2503         }
2504     }
2505
2506     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2507             ProcessRecord client) {
2508         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2509                 || app.treatLikeActivity;
2510         final boolean hasService = false; // not impl yet. app.services.size() > 0;
2511         if (!activityChange && hasActivity) {
2512             // The process has activities, so we are only allowing activity-based adjustments
2513             // to move it.  It should be kept in the front of the list with other
2514             // processes that have activities, and we don't want those to change their
2515             // order except due to activity operations.
2516             return;
2517         }
2518
2519         mLruSeq++;
2520         final long now = SystemClock.uptimeMillis();
2521         app.lastActivityTime = now;
2522
2523         // First a quick reject: if the app is already at the position we will
2524         // put it, then there is nothing to do.
2525         if (hasActivity) {
2526             final int N = mLruProcesses.size();
2527             if (N > 0 && mLruProcesses.get(N-1) == app) {
2528                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2529                 return;
2530             }
2531         } else {
2532             if (mLruProcessServiceStart > 0
2533                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2534                 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2535                 return;
2536             }
2537         }
2538
2539         int lrui = mLruProcesses.lastIndexOf(app);
2540
2541         if (app.persistent && lrui >= 0) {
2542             // We don't care about the position of persistent processes, as long as
2543             // they are in the list.
2544             if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2545             return;
2546         }
2547
2548         /* In progress: compute new position first, so we can avoid doing work
2549            if the process is not actually going to move.  Not yet working.
2550         int addIndex;
2551         int nextIndex;
2552         boolean inActivity = false, inService = false;
2553         if (hasActivity) {
2554             // Process has activities, put it at the very tipsy-top.
2555             addIndex = mLruProcesses.size();
2556             nextIndex = mLruProcessServiceStart;
2557             inActivity = true;
2558         } else if (hasService) {
2559             // Process has services, put it at the top of the service list.
2560             addIndex = mLruProcessActivityStart;
2561             nextIndex = mLruProcessServiceStart;
2562             inActivity = true;
2563             inService = true;
2564         } else  {
2565             // Process not otherwise of interest, it goes to the top of the non-service area.
2566             addIndex = mLruProcessServiceStart;
2567             if (client != null) {
2568                 int clientIndex = mLruProcesses.lastIndexOf(client);
2569                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2570                         + app);
2571                 if (clientIndex >= 0 && addIndex > clientIndex) {
2572                     addIndex = clientIndex;
2573                 }
2574             }
2575             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2576         }
2577
2578         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2579                 + mLruProcessActivityStart + "): " + app);
2580         */
2581
2582         if (lrui >= 0) {
2583             if (lrui < mLruProcessActivityStart) {
2584                 mLruProcessActivityStart--;
2585             }
2586             if (lrui < mLruProcessServiceStart) {
2587                 mLruProcessServiceStart--;
2588             }
2589             /*
2590             if (addIndex > lrui) {
2591                 addIndex--;
2592             }
2593             if (nextIndex > lrui) {
2594                 nextIndex--;
2595             }
2596             */
2597             mLruProcesses.remove(lrui);
2598         }
2599
2600         /*
2601         mLruProcesses.add(addIndex, app);
2602         if (inActivity) {
2603             mLruProcessActivityStart++;
2604         }
2605         if (inService) {
2606             mLruProcessActivityStart++;
2607         }
2608         */
2609
2610         int nextIndex;
2611         if (hasActivity) {
2612             final int N = mLruProcesses.size();
2613             if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2614                 // Process doesn't have activities, but has clients with
2615                 // activities...  move it up, but one below the top (the top
2616                 // should always have a real activity).
2617                 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2618                 mLruProcesses.add(N-1, app);
2619                 // To keep it from spamming the LRU list (by making a bunch of clients),
2620                 // we will push down any other entries owned by the app.
2621                 final int uid = app.info.uid;
2622                 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2623                     ProcessRecord subProc = mLruProcesses.get(i);
2624                     if (subProc.info.uid == uid) {
2625                         // We want to push this one down the list.  If the process after
2626                         // it is for the same uid, however, don't do so, because we don't
2627                         // want them internally to be re-ordered.
2628                         if (mLruProcesses.get(i-1).info.uid != uid) {
2629                             if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2630                                     + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2631                             ProcessRecord tmp = mLruProcesses.get(i);
2632                             mLruProcesses.set(i, mLruProcesses.get(i-1));
2633                             mLruProcesses.set(i-1, tmp);
2634                             i--;
2635                         }
2636                     } else {
2637                         // A gap, we can stop here.
2638                         break;
2639                     }
2640                 }
2641             } else {
2642                 // Process has activities, put it at the very tipsy-top.
2643                 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2644                 mLruProcesses.add(app);
2645             }
2646             nextIndex = mLruProcessServiceStart;
2647         } else if (hasService) {
2648             // Process has services, put it at the top of the service list.
2649             if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2650             mLruProcesses.add(mLruProcessActivityStart, app);
2651             nextIndex = mLruProcessServiceStart;
2652             mLruProcessActivityStart++;
2653         } else  {
2654             // Process not otherwise of interest, it goes to the top of the non-service area.
2655             int index = mLruProcessServiceStart;
2656             if (client != null) {
2657                 // If there is a client, don't allow the process to be moved up higher
2658                 // in the list than that client.
2659                 int clientIndex = mLruProcesses.lastIndexOf(client);
2660                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2661                         + " when updating " + app);
2662                 if (clientIndex <= lrui) {
2663                     // Don't allow the client index restriction to push it down farther in the
2664                     // list than it already is.
2665                     clientIndex = lrui;
2666                 }
2667                 if (clientIndex >= 0 && index > clientIndex) {
2668                     index = clientIndex;
2669                 }
2670             }
2671             if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2672             mLruProcesses.add(index, app);
2673             nextIndex = index-1;
2674             mLruProcessActivityStart++;
2675             mLruProcessServiceStart++;
2676         }
2677
2678         // If the app is currently using a content provider or service,
2679         // bump those processes as well.
2680         for (int j=app.connections.size()-1; j>=0; j--) {
2681             ConnectionRecord cr = app.connections.valueAt(j);
2682             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2683                     && cr.binding.service.app != null
2684                     && cr.binding.service.app.lruSeq != mLruSeq
2685                     && !cr.binding.service.app.persistent) {
2686                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2687                         "service connection", cr, app);
2688             }
2689         }
2690         for (int j=app.conProviders.size()-1; j>=0; j--) {
2691             ContentProviderRecord cpr = app.conProviders.get(j).provider;
2692             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2693                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2694                         "provider reference", cpr, app);
2695             }
2696         }
2697     }
2698
2699     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2700         if (uid == Process.SYSTEM_UID) {
2701             // The system gets to run in any process.  If there are multiple
2702             // processes with the same uid, just pick the first (this
2703             // should never happen).
2704             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2705             if (procs == null) return null;
2706             final int procCount = procs.size();
2707             for (int i = 0; i < procCount; i++) {
2708                 final int procUid = procs.keyAt(i);
2709                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2710                     // Don't use an app process or different user process for system component.
2711                     continue;
2712                 }
2713                 return procs.valueAt(i);
2714             }
2715         }
2716         ProcessRecord proc = mProcessNames.get(processName, uid);
2717         if (false && proc != null && !keepIfLarge
2718                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2719                 && proc.lastCachedPss >= 4000) {
2720             // Turn this condition on to cause killing to happen regularly, for testing.
2721             if (proc.baseProcessTracker != null) {
2722                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2723             }
2724             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2725         } else if (proc != null && !keepIfLarge
2726                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2727                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2728             if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2729             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2730                 if (proc.baseProcessTracker != null) {
2731                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2732                 }
2733                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2734             }
2735         }
2736         return proc;
2737     }
2738
2739     void ensurePackageDexOpt(String packageName) {
2740         IPackageManager pm = AppGlobals.getPackageManager();
2741         try {
2742             if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2743                 mDidDexOpt = true;
2744             }
2745         } catch (RemoteException e) {
2746         }
2747     }
2748
2749     boolean isNextTransitionForward() {
2750         int transit = mWindowManager.getPendingAppTransition();
2751         return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2752                 || transit == AppTransition.TRANSIT_TASK_OPEN
2753                 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2754     }
2755
2756     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2757             String processName, String abiOverride, int uid, Runnable crashHandler) {
2758         synchronized(this) {
2759             ApplicationInfo info = new ApplicationInfo();
2760             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2761             // For isolated processes, the former contains the parent's uid and the latter the
2762             // actual uid of the isolated process.
2763             // In the special case introduced by this method (which is, starting an isolated
2764             // process directly from the SystemServer without an actual parent app process) the
2765             // closest thing to a parent's uid is SYSTEM_UID.
2766             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2767             // the |isolated| logic in the ProcessRecord constructor.
2768             info.uid = Process.SYSTEM_UID;
2769             info.processName = processName;
2770             info.className = entryPoint;
2771             info.packageName = "android";
2772             ProcessRecord proc = startProcessLocked(processName, info /* info */,
2773                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2774                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2775                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2776                     crashHandler);
2777             return proc != null ? proc.pid : 0;
2778         }
2779     }
2780
2781     final ProcessRecord startProcessLocked(String processName,
2782             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2783             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2784             boolean isolated, boolean keepIfLarge) {
2785         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2786                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2787                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2788                 null /* crashHandler */);
2789     }
2790
2791     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2792             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2793             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2794             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2795         long startTime = SystemClock.elapsedRealtime();
2796         ProcessRecord app;
2797         if (!isolated) {
2798             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2799             checkTime(startTime, "startProcess: after getProcessRecord");
2800         } else {
2801             // If this is an isolated process, it can't re-use an existing process.
2802             app = null;
2803         }
2804         // We don't have to do anything more if:
2805         // (1) There is an existing application record; and
2806         // (2) The caller doesn't think it is dead, OR there is no thread
2807         //     object attached to it so we know it couldn't have crashed; and
2808         // (3) There is a pid assigned to it, so it is either starting or
2809         //     already running.
2810         if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2811                 + " app=" + app + " knownToBeDead=" + knownToBeDead
2812                 + " thread=" + (app != null ? app.thread : null)
2813                 + " pid=" + (app != null ? app.pid : -1));
2814         if (app != null && app.pid > 0) {
2815             if (!knownToBeDead || app.thread == null) {
2816                 // We already have the app running, or are waiting for it to
2817                 // come up (we have a pid but not yet its thread), so keep it.
2818                 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2819                 // If this is a new package in the process, add the package to the list
2820                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2821                 checkTime(startTime, "startProcess: done, added package to proc");
2822                 return app;
2823             }
2824
2825             // An application record is attached to a previous process,
2826             // clean it up now.
2827             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2828             checkTime(startTime, "startProcess: bad proc running, killing");
2829             Process.killProcessGroup(app.uid, app.pid);
2830             handleAppDiedLocked(app, true, true);
2831             checkTime(startTime, "startProcess: done killing old proc");
2832         }
2833
2834         String hostingNameStr = hostingName != null
2835                 ? hostingName.flattenToShortString() : null;
2836
2837         if (!isolated) {
2838             if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2839                 // If we are in the background, then check to see if this process
2840                 // is bad.  If so, we will just silently fail.
2841                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2842                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2843                             + "/" + info.processName);
2844                     return null;
2845                 }
2846             } else {
2847                 // When the user is explicitly starting a process, then clear its
2848                 // crash count so that we won't make it bad until they see at
2849                 // least one crash dialog again, and make the process good again
2850                 // if it had been bad.
2851                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2852                         + "/" + info.processName);
2853                 mProcessCrashTimes.remove(info.processName, info.uid);
2854                 if (mBadProcesses.get(info.processName, info.uid) != null) {
2855                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2856                             UserHandle.getUserId(info.uid), info.uid,
2857                             info.processName);
2858                     mBadProcesses.remove(info.processName, info.uid);
2859                     if (app != null) {
2860                         app.bad = false;
2861                     }
2862                 }
2863             }
2864         }
2865
2866         if (app == null) {
2867             checkTime(startTime, "startProcess: creating new process record");
2868             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2869             if (app == null) {
2870                 Slog.w(TAG, "Failed making new process record for "
2871                         + processName + "/" + info.uid + " isolated=" + isolated);
2872                 return null;
2873             }
2874             app.crashHandler = crashHandler;
2875             mProcessNames.put(processName, app.uid, app);
2876             if (isolated) {
2877                 mIsolatedProcesses.put(app.uid, app);
2878             }
2879             checkTime(startTime, "startProcess: done creating new process record");
2880         } else {
2881             // If this is a new package in the process, add the package to the list
2882             app.addPackage(info.packageName, info.versionCode, mProcessStats);
2883             checkTime(startTime, "startProcess: added package to existing proc");
2884         }
2885
2886         // If the system is not ready yet, then hold off on starting this
2887         // process until it is.
2888         if (!mProcessesReady
2889                 && !isAllowedWhileBooting(info)
2890                 && !allowWhileBooting) {
2891             if (!mProcessesOnHold.contains(app)) {
2892                 mProcessesOnHold.add(app);
2893             }
2894             if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2895             checkTime(startTime, "startProcess: returning with proc on hold");
2896             return app;
2897         }
2898
2899         checkTime(startTime, "startProcess: stepping in to startProcess");
2900         startProcessLocked(
2901                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2902         checkTime(startTime, "startProcess: done starting proc!");
2903         return (app.pid != 0) ? app : null;
2904     }
2905
2906     boolean isAllowedWhileBooting(ApplicationInfo ai) {
2907         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2908     }
2909
2910     private final void startProcessLocked(ProcessRecord app,
2911             String hostingType, String hostingNameStr) {
2912         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2913                 null /* entryPoint */, null /* entryPointArgs */);
2914     }
2915
2916     private final void startProcessLocked(ProcessRecord app, String hostingType,
2917             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2918         long startTime = SystemClock.elapsedRealtime();
2919         if (app.pid > 0 && app.pid != MY_PID) {
2920             checkTime(startTime, "startProcess: removing from pids map");
2921             synchronized (mPidsSelfLocked) {
2922                 mPidsSelfLocked.remove(app.pid);
2923                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2924             }
2925             checkTime(startTime, "startProcess: done removing from pids map");
2926             app.setPid(0);
2927         }
2928
2929         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2930                 "startProcessLocked removing on hold: " + app);
2931         mProcessesOnHold.remove(app);
2932
2933         checkTime(startTime, "startProcess: starting to update cpu stats");
2934         updateCpuStats();
2935         checkTime(startTime, "startProcess: done updating cpu stats");
2936
2937         try {
2938             int uid = app.uid;
2939
2940             int[] gids = null;
2941             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2942             if (!app.isolated) {
2943                 int[] permGids = null;
2944                 try {
2945                     checkTime(startTime, "startProcess: getting gids from package manager");
2946                     final PackageManager pm = mContext.getPackageManager();
2947                     permGids = pm.getPackageGids(app.info.packageName);
2948
2949                     if (Environment.isExternalStorageEmulated()) {
2950                         checkTime(startTime, "startProcess: checking external storage perm");
2951                         if (pm.checkPermission(
2952                                 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2953                                 app.info.packageName) == PERMISSION_GRANTED) {
2954                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2955                         } else {
2956                             mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2957                         }
2958                     }
2959                 } catch (PackageManager.NameNotFoundException e) {
2960                     Slog.w(TAG, "Unable to retrieve gids", e);
2961                 }
2962
2963                 /*
2964                  * Add shared application and profile GIDs so applications can share some
2965                  * resources like shared libraries and access user-wide resources
2966                  */
2967                 if (permGids == null) {
2968                     gids = new int[2];
2969                 } else {
2970                     gids = new int[permGids.length + 2];
2971                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
2972                 }
2973                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2974                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2975             }
2976             checkTime(startTime, "startProcess: building args");
2977             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2978                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2979                         && mTopComponent != null
2980                         && app.processName.equals(mTopComponent.getPackageName())) {
2981                     uid = 0;
2982                 }
2983                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2984                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2985                     uid = 0;
2986                 }
2987             }
2988             int debugFlags = 0;
2989             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2990                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2991                 // Also turn on CheckJNI for debuggable apps. It's quite
2992                 // awkward to turn on otherwise.
2993                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2994             }
2995             // Run the app in safe mode if its manifest requests so or the
2996             // system is booted in safe mode.
2997             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2998                 mSafeMode == true) {
2999                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3000             }
3001             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3002                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3003             }
3004             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3005                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3006             }
3007             if ("1".equals(SystemProperties.get("debug.assert"))) {
3008                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3009             }
3010
3011             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3012             if (requiredAbi == null) {
3013                 requiredAbi = Build.SUPPORTED_ABIS[0];
3014             }
3015
3016             String instructionSet = null;
3017             if (app.info.primaryCpuAbi != null) {
3018                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3019             }
3020
3021             app.gids = gids;
3022             app.requiredAbi = requiredAbi;
3023             app.instructionSet = instructionSet;
3024
3025             // Start the process.  It will either succeed and return a result containing
3026             // the PID of the new process, or else throw a RuntimeException.
3027             boolean isActivityProcess = (entryPoint == null);
3028             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3029             checkTime(startTime, "startProcess: asking zygote to start proc");
3030             Process.ProcessStartResult startResult = Process.start(entryPoint,
3031                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3032                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3033                     app.info.dataDir, entryPointArgs);
3034             checkTime(startTime, "startProcess: returned from zygote!");
3035
3036             if (app.isolated) {
3037                 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3038             }
3039             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3040             checkTime(startTime, "startProcess: done updating battery stats");
3041
3042             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043                     UserHandle.getUserId(uid), startResult.pid, uid,
3044                     app.processName, hostingType,
3045                     hostingNameStr != null ? hostingNameStr : "");
3046
3047             if (app.persistent) {
3048                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3049             }
3050
3051             checkTime(startTime, "startProcess: building log message");
3052             StringBuilder buf = mStringBuilder;
3053             buf.setLength(0);
3054             buf.append("Start proc ");
3055             buf.append(startResult.pid);
3056             buf.append(':');
3057             buf.append(app.processName);
3058             buf.append('/');
3059             UserHandle.formatUid(buf, uid);
3060             if (!isActivityProcess) {
3061                 buf.append(" [");
3062                 buf.append(entryPoint);
3063                 buf.append("]");
3064             }
3065             buf.append(" for ");
3066             buf.append(hostingType);
3067             if (hostingNameStr != null) {
3068                 buf.append(" ");
3069                 buf.append(hostingNameStr);
3070             }
3071             Slog.i(TAG, buf.toString());
3072             app.setPid(startResult.pid);
3073             app.usingWrapper = startResult.usingWrapper;
3074             app.removed = false;
3075             app.killed = false;
3076             app.killedByAm = false;
3077             checkTime(startTime, "startProcess: starting to update pids map");
3078             ProcessRecord oldApp;
3079             synchronized (mPidsSelfLocked) {
3080                 oldApp = mPidsSelfLocked.get(startResult.pid);
3081             }
3082             // If there is already an app occupying that pid that hasn't been cleaned up
3083             if (oldApp != null && !app.isolated) {
3084                 // Clean up anything relating to this pid first
3085                 Slog.w(TAG, "Reusing pid " + startResult.pid
3086                         + " while app is still mapped to it");
3087                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3088                         true /*replacingPid*/);
3089             }
3090             synchronized (mPidsSelfLocked) {
3091                 this.mPidsSelfLocked.put(startResult.pid, app);
3092                 if (isActivityProcess) {
3093                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3094                     msg.obj = app;
3095                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3096                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3097                 }
3098             }
3099             checkTime(startTime, "startProcess: done updating pids map");
3100         } catch (RuntimeException e) {
3101             // XXX do better error recovery.
3102             app.setPid(0);
3103             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3104             if (app.isolated) {
3105                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3106             }
3107             Slog.e(TAG, "Failure starting process " + app.processName, e);
3108         }
3109     }
3110
3111     void updateUsageStats(ActivityRecord component, boolean resumed) {
3112         if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3113         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3114         if (resumed) {
3115             if (mUsageStatsService != null) {
3116                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3117                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3118             }
3119             synchronized (stats) {
3120                 stats.noteActivityResumedLocked(component.app.uid);
3121             }
3122         } else {
3123             if (mUsageStatsService != null) {
3124                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3125                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3126             }
3127             synchronized (stats) {
3128                 stats.noteActivityPausedLocked(component.app.uid);
3129             }
3130         }
3131     }
3132
3133     Intent getHomeIntent() {
3134         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3135         intent.setComponent(mTopComponent);
3136         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3137             intent.addCategory(Intent.CATEGORY_HOME);
3138         }
3139         return intent;
3140     }
3141
3142     boolean startHomeActivityLocked(int userId, String reason) {
3143         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3144                 && mTopAction == null) {
3145             // We are running in factory test mode, but unable to find
3146             // the factory test app, so just sit around displaying the
3147             // error message and don't try to start anything.
3148             return false;
3149         }
3150         Intent intent = getHomeIntent();
3151         ActivityInfo aInfo =
3152             resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3153         if (aInfo != null) {
3154             intent.setComponent(new ComponentName(
3155                     aInfo.applicationInfo.packageName, aInfo.name));
3156             // Don't do this if the home app is currently being
3157             // instrumented.
3158             aInfo = new ActivityInfo(aInfo);
3159             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3160             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3161                     aInfo.applicationInfo.uid, true);
3162             if (app == null || app.instrumentationClass == null) {
3163                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3164                 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3165             }
3166         }
3167
3168         return true;
3169     }
3170
3171     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3172         ActivityInfo ai = null;
3173         ComponentName comp = intent.getComponent();
3174         try {
3175             if (comp != null) {
3176                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3177             } else {
3178                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3179                         intent,
3180                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3181                             flags, userId);
3182
3183                 if (info != null) {
3184                     ai = info.activityInfo;
3185                 }
3186             }
3187         } catch (RemoteException e) {
3188             // ignore
3189         }
3190
3191         return ai;
3192     }
3193
3194     /**
3195      * Starts the "new version setup screen" if appropriate.
3196      */
3197     void startSetupActivityLocked() {
3198         // Only do this once per boot.
3199         if (mCheckedForSetup) {
3200             return;
3201         }
3202
3203         // We will show this screen if the current one is a different
3204         // version than the last one shown, and we are not running in
3205         // low-level factory test mode.
3206         final ContentResolver resolver = mContext.getContentResolver();
3207         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3208                 Settings.Global.getInt(resolver,
3209                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3210             mCheckedForSetup = true;
3211
3212             // See if we should be showing the platform update setup UI.
3213             Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3214             List<ResolveInfo> ris = mContext.getPackageManager()
3215                     .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3216
3217             // We don't allow third party apps to replace this.
3218             ResolveInfo ri = null;
3219             for (int i=0; ris != null && i<ris.size(); i++) {
3220                 if ((ris.get(i).activityInfo.applicationInfo.flags
3221                         & ApplicationInfo.FLAG_SYSTEM) != 0) {
3222                     ri = ris.get(i);
3223                     break;
3224                 }
3225             }
3226
3227             if (ri != null) {
3228                 String vers = ri.activityInfo.metaData != null
3229                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3230                         : null;
3231                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3232                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3233                             Intent.METADATA_SETUP_VERSION);
3234                 }
3235                 String lastVers = Settings.Secure.getString(
3236                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3237                 if (vers != null && !vers.equals(lastVers)) {
3238                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3239                     intent.setComponent(new ComponentName(
3240                             ri.activityInfo.packageName, ri.activityInfo.name));
3241                     mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3242                             null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3243                             null);
3244                 }
3245             }
3246         }
3247     }
3248
3249     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3250         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3251     }
3252
3253     void enforceNotIsolatedCaller(String caller) {
3254         if (UserHandle.isIsolated(Binder.getCallingUid())) {
3255             throw new SecurityException("Isolated process not allowed to call " + caller);
3256         }
3257     }
3258
3259     void enforceShellRestriction(String restriction, int userHandle) {
3260         if (Binder.getCallingUid() == Process.SHELL_UID) {
3261             if (userHandle < 0
3262                     || mUserManager.hasUserRestriction(restriction, userHandle)) {
3263                 throw new SecurityException("Shell does not have permission to access user "
3264                         + userHandle);
3265             }
3266         }
3267     }
3268
3269     @Override
3270     public int getFrontActivityScreenCompatMode() {
3271         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3272         synchronized (this) {
3273             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3274         }
3275     }
3276
3277     @Override
3278     public void setFrontActivityScreenCompatMode(int mode) {
3279         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3280                 "setFrontActivityScreenCompatMode");
3281         synchronized (this) {
3282             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3283         }
3284     }
3285
3286     @Override
3287     public int getPackageScreenCompatMode(String packageName) {
3288         enforceNotIsolatedCaller("getPackageScreenCompatMode");
3289         synchronized (this) {
3290             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3291         }
3292     }
3293
3294     @Override
3295     public void setPackageScreenCompatMode(String packageName, int mode) {
3296         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3297                 "setPackageScreenCompatMode");
3298         synchronized (this) {
3299             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3300         }
3301     }
3302
3303     @Override
3304     public boolean getPackageAskScreenCompat(String packageName) {
3305         enforceNotIsolatedCaller("getPackageAskScreenCompat");
3306         synchronized (this) {
3307             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3308         }
3309     }
3310
3311     @Override
3312     public void setPackageAskScreenCompat(String packageName, boolean ask) {
3313         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3314                 "setPackageAskScreenCompat");
3315         synchronized (this) {
3316             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3317         }
3318     }
3319
3320     private void dispatchProcessesChanged() {
3321         int N;
3322         synchronized (this) {
3323             N = mPendingProcessChanges.size();
3324             if (mActiveProcessChanges.length < N) {
3325                 mActiveProcessChanges = new ProcessChangeItem[N];
3326             }
3327             mPendingProcessChanges.toArray(mActiveProcessChanges);
3328             mAvailProcessChanges.addAll(mPendingProcessChanges);
3329             mPendingProcessChanges.clear();
3330             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3331         }
3332
3333         int i = mProcessObservers.beginBroadcast();
3334         while (i > 0) {
3335             i--;
3336             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3337             if (observer != null) {
3338                 try {
3339                     for (int j=0; j<N; j++) {
3340                         ProcessChangeItem item = mActiveProcessChanges[j];
3341                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3342                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3343                                     + item.pid + " uid=" + item.uid + ": "
3344                                     + item.foregroundActivities);
3345                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
3346                                     item.foregroundActivities);
3347                         }
3348                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3349                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3350                                     + item.pid + " uid=" + item.uid + ": " + item.processState);
3351                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3352                         }
3353                     }
3354                 } catch (RemoteException e) {
3355                 }
3356             }
3357         }
3358         mProcessObservers.finishBroadcast();
3359     }
3360
3361     private void dispatchProcessDied(int pid, int uid) {
3362         int i = mProcessObservers.beginBroadcast();
3363         while (i > 0) {
3364             i--;
3365             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3366             if (observer != null) {
3367                 try {
3368                     observer.onProcessDied(pid, uid);
3369                 } catch (RemoteException e) {
3370                 }
3371             }
3372         }
3373         mProcessObservers.finishBroadcast();
3374     }
3375
3376     @Override
3377     public final int startActivity(IApplicationThread caller, String callingPackage,
3378             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3379             int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3380         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3381             resultWho, requestCode, startFlags, profilerInfo, options,
3382             UserHandle.getCallingUserId());
3383     }
3384
3385     @Override
3386     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3387             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3388             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3389         enforceNotIsolatedCaller("startActivity");
3390         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3391                 false, ALLOW_FULL_ONLY, "startActivity", null);
3392         // TODO: Switch to user app stacks here.
3393         return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3394                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3395                 profilerInfo, null, null, options, userId, null, null);
3396     }
3397
3398     @Override
3399     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3400             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3401             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3402
3403         // This is very dangerous -- it allows you to perform a start activity (including
3404         // permission grants) as any app that may launch one of your own activities.  So
3405         // we will only allow this to be done from activities that are part of the core framework,
3406         // and then only when they are running as the system.
3407         final ActivityRecord sourceRecord;
3408         final int targetUid;
3409         final String targetPackage;
3410         synchronized (this) {
3411             if (resultTo == null) {
3412                 throw new SecurityException("Must be called from an activity");
3413             }
3414             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3415             if (sourceRecord == null) {
3416                 throw new SecurityException("Called with bad activity token: " + resultTo);
3417             }
3418             if (!sourceRecord.info.packageName.equals("android")) {
3419                 throw new SecurityException(
3420                         "Must be called from an activity that is declared in the android package");
3421             }
3422             if (sourceRecord.app == null) {
3423                 throw new SecurityException("Called without a process attached to activity");
3424             }
3425             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3426                 // This is still okay, as long as this activity is running under the
3427                 // uid of the original calling activity.
3428                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3429                     throw new SecurityException(
3430                             "Calling activity in uid " + sourceRecord.app.uid
3431                                     + " must be system uid or original calling uid "
3432                                     + sourceRecord.launchedFromUid);
3433                 }
3434             }
3435             targetUid = sourceRecord.launchedFromUid;
3436             targetPackage = sourceRecord.launchedFromPackage;
3437         }
3438
3439         if (userId == UserHandle.USER_NULL) {
3440             userId = UserHandle.getUserId(sourceRecord.app.uid);
3441         }
3442
3443         // TODO: Switch to user app stacks here.
3444         try {
3445             int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3446                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3447                     null, null, options, userId, null, null);
3448             return ret;
3449         } catch (SecurityException e) {
3450             // XXX need to figure out how to propagate to original app.
3451             // A SecurityException here is generally actually a fault of the original
3452             // calling activity (such as a fairly granting permissions), so propagate it
3453             // back to them.
3454             /*
3455             StringBuilder msg = new StringBuilder();
3456             msg.append("While launching");
3457             msg.append(intent.toString());
3458             msg.append(": ");
3459             msg.append(e.getMessage());
3460             */
3461             throw e;
3462         }
3463     }
3464
3465     @Override
3466     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3467             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3468             int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3469         enforceNotIsolatedCaller("startActivityAndWait");
3470         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3471                 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3472         WaitResult res = new WaitResult();
3473         // TODO: Switch to user app stacks here.
3474         mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3475                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3476                 options, userId, null, null);
3477         return res;
3478     }
3479
3480     @Override
3481     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3482             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3483             int startFlags, Configuration config, Bundle options, int userId) {
3484         enforceNotIsolatedCaller("startActivityWithConfig");
3485         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3486                 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3487         // TODO: Switch to user app stacks here.
3488         int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3489                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3490                 null, null, config, options, userId, null, null);
3491         return ret;
3492     }
3493
3494     @Override
3495     public int startActivityIntentSender(IApplicationThread caller,
3496             IntentSender intent, Intent fillInIntent, String resolvedType,
3497             IBinder resultTo, String resultWho, int requestCode,
3498             int flagsMask, int flagsValues, Bundle options) {
3499         enforceNotIsolatedCaller("startActivityIntentSender");
3500         // Refuse possible leaked file descriptors
3501         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3502             throw new IllegalArgumentException("File descriptors passed in Intent");
3503         }
3504
3505         IIntentSender sender = intent.getTarget();
3506         if (!(sender instanceof PendingIntentRecord)) {
3507             throw new IllegalArgumentException("Bad PendingIntent object");
3508         }
3509
3510         PendingIntentRecord pir = (PendingIntentRecord)sender;
3511
3512         synchronized (this) {
3513             // If this is coming from the currently resumed activity, it is
3514             // effectively saying that app switches are allowed at this point.
3515             final ActivityStack stack = getFocusedStack();
3516             if (stack.mResumedActivity != null &&
3517                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3518                 mAppSwitchesAllowedTime = 0;
3519             }
3520         }
3521         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3522                 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3523         return ret;
3524     }
3525
3526     @Override
3527     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3528             Intent intent, String resolvedType, IVoiceInteractionSession session,
3529             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3530             Bundle options, int userId) {
3531         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3532                 != PackageManager.PERMISSION_GRANTED) {
3533             String msg = "Permission Denial: startVoiceActivity() from pid="
3534                     + Binder.getCallingPid()
3535                     + ", uid=" + Binder.getCallingUid()
3536                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3537             Slog.w(TAG, msg);
3538             throw new SecurityException(msg);
3539         }
3540         if (session == null || interactor == null) {
3541             throw new NullPointerException("null session or interactor");
3542         }
3543         userId = handleIncomingUser(callingPid, callingUid, userId,
3544                 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3545         // TODO: Switch to user app stacks here.
3546         return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3547                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3548                 null, options, userId, null, null);
3549     }
3550
3551     @Override
3552     public boolean startNextMatchingActivity(IBinder callingActivity,
3553             Intent intent, Bundle options) {
3554         // Refuse possible leaked file descriptors
3555         if (intent != null && intent.hasFileDescriptors() == true) {
3556             throw new IllegalArgumentException("File descriptors passed in Intent");
3557         }
3558
3559         synchronized (this) {
3560             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3561             if (r == null) {
3562                 ActivityOptions.abort(options);
3563                 return false;
3564             }
3565             if (r.app == null || r.app.thread == null) {
3566                 // The caller is not running...  d'oh!
3567                 ActivityOptions.abort(options);
3568                 return false;
3569             }
3570             intent = new Intent(intent);
3571             // The caller is not allowed to change the data.
3572             intent.setDataAndType(r.intent.getData(), r.intent.getType());
3573             // And we are resetting to find the next component...
3574             intent.setComponent(null);
3575
3576             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3577
3578             ActivityInfo aInfo = null;
3579             try {
3580                 List<ResolveInfo> resolves =
3581                     AppGlobals.getPackageManager().queryIntentActivities(
3582                             intent, r.resolvedType,
3583                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3584                             UserHandle.getCallingUserId());
3585
3586                 // Look for the original activity in the list...
3587                 final int N = resolves != null ? resolves.size() : 0;
3588                 for (int i=0; i<N; i++) {
3589                     ResolveInfo rInfo = resolves.get(i);
3590                     if (rInfo.activityInfo.packageName.equals(r.packageName)
3591                             && rInfo.activityInfo.name.equals(r.info.name)) {
3592                         // We found the current one...  the next matching is
3593                         // after it.
3594                         i++;
3595                         if (i<N) {
3596                             aInfo = resolves.get(i).activityInfo;
3597                         }
3598                         if (debug) {
3599                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
3600                                     + "/" + r.info.name);
3601                             Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3602                                     + "/" + aInfo.name);
3603                         }
3604                         break;
3605                     }
3606                 }
3607             } catch (RemoteException e) {
3608             }
3609
3610             if (aInfo == null) {
3611                 // Nobody who is next!
3612                 ActivityOptions.abort(options);
3613                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3614                 return false;
3615             }
3616
3617             intent.setComponent(new ComponentName(
3618                     aInfo.applicationInfo.packageName, aInfo.name));
3619             intent.setFlags(intent.getFlags()&~(
3620                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3621                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
3622                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3623                     Intent.FLAG_ACTIVITY_NEW_TASK));
3624
3625             // Okay now we need to start the new activity, replacing the
3626             // currently running activity.  This is a little tricky because
3627             // we want to start the new one as if the current one is finished,
3628             // but not finish the current one first so that there is no flicker.
3629             // And thus...
3630             final boolean wasFinishing = r.finishing;
3631             r.finishing = true;
3632
3633             // Propagate reply information over to the new activity.
3634             final ActivityRecord resultTo = r.resultTo;
3635             final String resultWho = r.resultWho;
3636             final int requestCode = r.requestCode;
3637             r.resultTo = null;
3638             if (resultTo != null) {
3639                 resultTo.removeResultsLocked(r, resultWho, requestCode);
3640             }
3641
3642             final long origId = Binder.clearCallingIdentity();
3643             int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3644                     r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3645                     resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3646                     -1, r.launchedFromUid, 0, options, false, null, null, null);
3647             Binder.restoreCallingIdentity(origId);
3648
3649             r.finishing = wasFinishing;
3650             if (res != ActivityManager.START_SUCCESS) {
3651                 return false;
3652             }
3653             return true;
3654         }
3655     }
3656
3657     @Override
3658     public final int startActivityFromRecents(int taskId, Bundle options) {
3659         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3660             String msg = "Permission Denial: startActivityFromRecents called without " +
3661                     START_TASKS_FROM_RECENTS;
3662             Slog.w(TAG, msg);
3663             throw new SecurityException(msg);
3664         }
3665         return startActivityFromRecentsInner(taskId, options);
3666     }
3667
3668     final int startActivityFromRecentsInner(int taskId, Bundle options) {
3669         final TaskRecord task;
3670         final int callingUid;
3671         final String callingPackage;
3672         final Intent intent;
3673         final int userId;
3674         synchronized (this) {
3675             task = recentTaskForIdLocked(taskId);
3676             if (task == null) {
3677                 throw new IllegalArgumentException("Task " + taskId + " not found.");
3678             }
3679             if (task.getRootActivity() != null) {
3680                 moveTaskToFrontLocked(task.taskId, 0, null);
3681                 return ActivityManager.START_TASK_TO_FRONT;
3682             }
3683             callingUid = task.mCallingUid;
3684             callingPackage = task.mCallingPackage;
3685             intent = task.intent;
3686             intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3687             userId = task.userId;
3688         }
3689         return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3690                 options, userId, null, task);
3691     }
3692
3693     final int startActivityInPackage(int uid, String callingPackage,
3694             Intent intent, String resolvedType, IBinder resultTo,
3695             String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3696             IActivityContainer container, TaskRecord inTask) {
3697
3698         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3700
3701         // TODO: Switch to user app stacks here.
3702         int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3703                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3704                 null, null, null, options, userId, container, inTask);
3705         return ret;
3706     }
3707
3708     @Override
3709     public final int startActivities(IApplicationThread caller, String callingPackage,
3710             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3711             int userId) {
3712         enforceNotIsolatedCaller("startActivities");
3713         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3714                 false, ALLOW_FULL_ONLY, "startActivity", null);
3715         // TODO: Switch to user app stacks here.
3716         int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3717                 resolvedTypes, resultTo, options, userId);
3718         return ret;
3719     }
3720
3721     final int startActivitiesInPackage(int uid, String callingPackage,
3722             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3723             Bundle options, int userId) {
3724
3725         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3726                 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3727         // TODO: Switch to user app stacks here.
3728         int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3729                 resultTo, options, userId);
3730         return ret;
3731     }
3732
3733     //explicitly remove thd old information in mRecentTasks when removing existing user.
3734     private void removeRecentTasksForUserLocked(int userId) {
3735         if(userId <= 0) {
3736             Slog.i(TAG, "Can't remove recent task on user " + userId);
3737             return;
3738         }
3739
3740         for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3741             TaskRecord tr = mRecentTasks.get(i);
3742             if (tr.userId == userId) {
3743                 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3744                         + " when finishing user" + userId);
3745                 mRecentTasks.remove(i);
3746                 tr.removedFromRecents();
3747             }
3748         }
3749
3750         // Remove tasks from persistent storage.
3751         notifyTaskPersisterLocked(null, true);
3752     }
3753
3754     // Sort by taskId
3755     private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3756         @Override
3757         public int compare(TaskRecord lhs, TaskRecord rhs) {
3758             return rhs.taskId - lhs.taskId;
3759         }
3760     };
3761
3762     // Extract the affiliates of the chain containing mRecentTasks[start].
3763     private int processNextAffiliateChainLocked(int start) {
3764         final TaskRecord startTask = mRecentTasks.get(start);
3765         final int affiliateId = startTask.mAffiliatedTaskId;
3766
3767         // Quick identification of isolated tasks. I.e. those not launched behind.
3768         if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3769                 startTask.mNextAffiliate == null) {
3770             // There is still a slim chance that there are other tasks that point to this task
3771             // and that the chain is so messed up that this task no longer points to them but
3772             // the gain of this optimization outweighs the risk.
3773             startTask.inRecents = true;
3774             return start + 1;
3775         }
3776
3777         // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3778         mTmpRecents.clear();
3779         for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3780             final TaskRecord task = mRecentTasks.get(i);
3781             if (task.mAffiliatedTaskId == affiliateId) {
3782                 mRecentTasks.remove(i);
3783                 mTmpRecents.add(task);
3784             }
3785         }
3786
3787         // Sort them all by taskId. That is the order they were create in and that order will
3788         // always be correct.
3789         Collections.sort(mTmpRecents, mTaskRecordComparator);
3790
3791         // Go through and fix up the linked list.
3792         // The first one is the end of the chain and has no next.
3793         final TaskRecord first = mTmpRecents.get(0);
3794         first.inRecents = true;
3795         if (first.mNextAffiliate != null) {
3796             Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3797             first.setNextAffiliate(null);
3798             notifyTaskPersisterLocked(first, false);
3799         }
3800         // Everything in the middle is doubly linked from next to prev.
3801         final int tmpSize = mTmpRecents.size();
3802         for (int i = 0; i < tmpSize - 1; ++i) {
3803             final TaskRecord next = mTmpRecents.get(i);
3804             final TaskRecord prev = mTmpRecents.get(i + 1);
3805             if (next.mPrevAffiliate != prev) {
3806                 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3807                         " setting prev=" + prev);
3808                 next.setPrevAffiliate(prev);
3809                 notifyTaskPersisterLocked(next, false);
3810             }
3811             if (prev.mNextAffiliate != next) {
3812                 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3813                         " setting next=" + next);
3814                 prev.setNextAffiliate(next);
3815                 notifyTaskPersisterLocked(prev, false);
3816             }
3817             prev.inRecents = true;
3818         }
3819         // The last one is the beginning of the list and has no prev.
3820         final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3821         if (last.mPrevAffiliate != null) {
3822             Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3823             last.setPrevAffiliate(null);
3824             notifyTaskPersisterLocked(last, false);
3825         }
3826
3827         // Insert the group back into mRecentTasks at start.
3828         mRecentTasks.addAll(start, mTmpRecents);
3829
3830         // Let the caller know where we left off.
3831         return start + tmpSize;
3832     }
3833
3834     /**
3835      * Update the recent tasks lists: make sure tasks should still be here (their
3836      * applications / activities still exist), update their availability, fixup ordering
3837      * of affiliations.
3838      */
3839     void cleanupRecentTasksLocked(int userId) {
3840         if (mRecentTasks == null) {
3841             // Happens when called from the packagemanager broadcast before boot.
3842             return;
3843         }
3844
3845         final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3846         final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3847         final IPackageManager pm = AppGlobals.getPackageManager();
3848         final ActivityInfo dummyAct = new ActivityInfo();
3849         final ApplicationInfo dummyApp = new ApplicationInfo();
3850
3851         int N = mRecentTasks.size();
3852
3853         int[] users = userId == UserHandle.USER_ALL
3854                 ? getUsersLocked() : new int[] { userId };
3855         for (int user : users) {
3856             for (int i = 0; i < N; i++) {
3857                 TaskRecord task = mRecentTasks.get(i);
3858                 if (task.userId != user) {
3859                     // Only look at tasks for the user ID of interest.
3860                     continue;
3861                 }
3862                 if (task.autoRemoveRecents && task.getTopActivity() == null) {
3863                     // This situation is broken, and we should just get rid of it now.
3864                     mRecentTasks.remove(i);
3865                     task.removedFromRecents();
3866                     i--;
3867                     N--;
3868                     Slog.w(TAG, "Removing auto-remove without activity: " + task);
3869                     continue;
3870                 }
3871                 // Check whether this activity is currently available.
3872                 if (task.realActivity != null) {
3873                     ActivityInfo ai = availActCache.get(task.realActivity);
3874                     if (ai == null) {
3875                         try {
3876                             ai = pm.getActivityInfo(task.realActivity,
3877                                     PackageManager.GET_UNINSTALLED_PACKAGES
3878                                     | PackageManager.GET_DISABLED_COMPONENTS, user);
3879                         } catch (RemoteException e) {
3880                             // Will never happen.
3881                             continue;
3882                         }
3883                         if (ai == null) {
3884                             ai = dummyAct;
3885                         }
3886                         availActCache.put(task.realActivity, ai);
3887                     }
3888                     if (ai == dummyAct) {
3889                         // This could be either because the activity no longer exists, or the
3890                         // app is temporarily gone.  For the former we want to remove the recents
3891                         // entry; for the latter we want to mark it as unavailable.
3892                         ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3893                         if (app == null) {
3894                             try {
3895                                 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3896                                         PackageManager.GET_UNINSTALLED_PACKAGES
3897                                         | PackageManager.GET_DISABLED_COMPONENTS, user);
3898                             } catch (RemoteException e) {
3899                                 // Will never happen.
3900                                 continue;
3901                             }
3902                             if (app == null) {
3903                                 app = dummyApp;
3904                             }
3905                             availAppCache.put(task.realActivity.getPackageName(), app);
3906                         }
3907                         if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3908                             // Doesn't exist any more!  Good-bye.
3909                             mRecentTasks.remove(i);
3910                             task.removedFromRecents();
3911                             i--;
3912                             N--;
3913                             Slog.w(TAG, "Removing no longer valid recent: " + task);
3914                             continue;
3915                         } else {
3916                             // Otherwise just not available for now.
3917                             if (task.isAvailable) {
3918                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3919                                         + task);
3920                             }
3921                             task.isAvailable = false;
3922                         }
3923                     } else {
3924                         if (!ai.enabled || !ai.applicationInfo.enabled
3925                                 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3926                             if (task.isAvailable) {
3927                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3928                                         + task + " (enabled=" + ai.enabled + "/"
3929                                         + ai.applicationInfo.enabled +  " flags="
3930                                         + Integer.toHexString(ai.applicationInfo.flags) + ")");
3931                             }
3932                             task.isAvailable = false;
3933                         } else {
3934                             if (!task.isAvailable) {
3935                                 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3936                                         + task);
3937                             }
3938                             task.isAvailable = true;
3939                         }
3940                     }
3941                 }
3942             }
3943         }
3944
3945         // Verify the affiliate chain for each task.
3946         for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3947         }
3948
3949         mTmpRecents.clear();
3950         // mRecentTasks is now in sorted, affiliated order.
3951     }
3952
3953     private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3954         int N = mRecentTasks.size();
3955         TaskRecord top = task;
3956         int topIndex = taskIndex;
3957         while (top.mNextAffiliate != null && topIndex > 0) {
3958             top = top.mNextAffiliate;
3959             topIndex--;
3960         }
3961         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3962                 + topIndex + " from intial " + taskIndex);
3963         // Find the end of the chain, doing a sanity check along the way.
3964         boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3965         int endIndex = topIndex;
3966         TaskRecord prev = top;
3967         while (endIndex < N) {
3968             TaskRecord cur = mRecentTasks.get(endIndex);
3969             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3970                     + endIndex + " " + cur);
3971             if (cur == top) {
3972                 // Verify start of the chain.
3973                 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3974                     Slog.wtf(TAG, "Bad chain @" + endIndex
3975                             + ": first task has next affiliate: " + prev);
3976                     sane = false;
3977                     break;
3978                 }
3979             } else {
3980                 // Verify middle of the chain's next points back to the one before.
3981                 if (cur.mNextAffiliate != prev
3982                         || cur.mNextAffiliateTaskId != prev.taskId) {
3983                     Slog.wtf(TAG, "Bad chain @" + endIndex
3984                             + ": middle task " + cur + " @" + endIndex
3985                             + " has bad next affiliate "
3986                             + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3987                             + ", expected " + prev);
3988                     sane = false;
3989                     break;
3990                 }
3991             }
3992             if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3993                 // Chain ends here.
3994                 if (cur.mPrevAffiliate != null) {
3995                     Slog.wtf(TAG, "Bad chain @" + endIndex
3996                             + ": last task " + cur + " has previous affiliate "
3997                             + cur.mPrevAffiliate);
3998                     sane = false;
3999                 }
4000                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4001                 break;
4002             } else {
4003                 // Verify middle of the chain's prev points to a valid item.
4004                 if (cur.mPrevAffiliate == null) {
4005                     Slog.wtf(TAG, "Bad chain @" + endIndex
4006                             + ": task " + cur + " has previous affiliate "
4007                             + cur.mPrevAffiliate + " but should be id "
4008                             + cur.mPrevAffiliate);
4009                     sane = false;
4010                     break;
4011                 }
4012             }
4013             if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4014                 Slog.wtf(TAG, "Bad chain @" + endIndex
4015                         + ": task " + cur + " has affiliated id "
4016                         + cur.mAffiliatedTaskId + " but should be "
4017                         + task.mAffiliatedTaskId);
4018                 sane = false;
4019                 break;
4020             }
4021             prev = cur;
4022             endIndex++;
4023             if (endIndex >= N) {
4024                 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4025                         + ": last task " + prev);
4026                 sane = false;
4027                 break;
4028             }
4029         }
4030         if (sane) {
4031             if (endIndex < taskIndex) {
4032                 Slog.wtf(TAG, "Bad chain @" + endIndex
4033                         + ": did not extend to task " + task + " @" + taskIndex);
4034                 sane = false;
4035             }
4036         }
4037         if (sane) {
4038             // All looks good, we can just move all of the affiliated tasks
4039             // to the top.
4040             for (int i=topIndex; i<=endIndex; i++) {
4041                 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4042                         + " from " + i + " to " + (i-topIndex));
4043                 TaskRecord cur = mRecentTasks.remove(i);
4044                 mRecentTasks.add(i-topIndex, cur);
4045             }
4046             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4047                     + " to " + endIndex);
4048             return true;
4049         }
4050
4051         // Whoops, couldn't do it.
4052         return false;
4053     }
4054
4055     final void addRecentTaskLocked(TaskRecord task) {
4056         final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4057                 || task.mNextAffiliateTaskId != INVALID_TASK_ID
4058                 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4059
4060         int N = mRecentTasks.size();
4061         // Quick case: check if the top-most recent task is the same.
4062         if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4063             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4064             return;
4065         }
4066         // Another quick case: check if this is part of a set of affiliated
4067         // tasks that are at the top.
4068         if (isAffiliated && N > 0 && task.inRecents
4069                 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4070             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4071                     + " at top when adding " + task);
4072             return;
4073         }
4074         // Another quick case: never add voice sessions.
4075         if (task.voiceSession != null) {
4076             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4077             return;
4078         }
4079
4080         boolean needAffiliationFix = false;
4081
4082         // Slightly less quick case: the task is already in recents, so all we need
4083         // to do is move it.
4084         if (task.inRecents) {
4085             int taskIndex = mRecentTasks.indexOf(task);
4086             if (taskIndex >= 0) {
4087                 if (!isAffiliated) {
4088                     // Simple case: this is not an affiliated task, so we just move it to the front.
4089                     mRecentTasks.remove(taskIndex);
4090                     mRecentTasks.add(0, task);
4091                     notifyTaskPersisterLocked(task, false);
4092                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4093                             + " from " + taskIndex);
4094                     return;
4095                 } else {
4096                     // More complicated: need to keep all affiliated tasks together.
4097                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4098                         // All went well.
4099                         return;
4100                     }
4101
4102                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4103                     // everything and then go through our general path of adding a new task.
4104                     needAffiliationFix = true;
4105                 }
4106             } else {
4107                 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4108                 needAffiliationFix = true;
4109             }
4110         }
4111
4112         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4113         trimRecentsForTaskLocked(task, true);
4114
4115         N = mRecentTasks.size();
4116         while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4117             final TaskRecord tr = mRecentTasks.remove(N - 1);
4118             tr.removedFromRecents();
4119             N--;
4120         }
4121         task.inRecents = true;
4122         if (!isAffiliated || needAffiliationFix) {
4123             // If this is a simple non-affiliated task, or we had some failure trying to
4124             // handle it as part of an affilated task, then just place it at the top.
4125             mRecentTasks.add(0, task);
4126         } else if (isAffiliated) {
4127             // If this is a new affiliated task, then move all of the affiliated tasks
4128             // to the front and insert this new one.
4129             TaskRecord other = task.mNextAffiliate;
4130             if (other == null) {
4131                 other = task.mPrevAffiliate;
4132             }
4133             if (other != null) {
4134                 int otherIndex = mRecentTasks.indexOf(other);
4135                 if (otherIndex >= 0) {
4136                     // Insert new task at appropriate location.
4137                     int taskIndex;
4138                     if (other == task.mNextAffiliate) {
4139                         // We found the index of our next affiliation, which is who is
4140                         // before us in the list, so add after that point.
4141                         taskIndex = otherIndex+1;
4142                     } else {
4143                         // We found the index of our previous affiliation, which is who is
4144                         // after us in the list, so add at their position.
4145                         taskIndex = otherIndex;
4146                     }
4147                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4148                             + taskIndex + ": " + task);
4149                     mRecentTasks.add(taskIndex, task);
4150
4151                     // Now move everything to the front.
4152                     if (moveAffiliatedTasksToFront(task, taskIndex)) {
4153                         // All went well.
4154                         return;
4155                     }
4156
4157                     // Uh oh...  something bad in the affiliation chain, try to rebuild
4158                     // everything and then go through our general path of adding a new task.
4159                     needAffiliationFix = true;
4160                 } else {
4161                     if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4162                             + other);
4163                     needAffiliationFix = true;
4164                 }
4165             } else {
4166                 if (DEBUG_RECENTS) Slog.d(TAG,
4167                         "addRecent: adding affiliated task without next/prev:" + task);
4168                 needAffiliationFix = true;
4169             }
4170         }
4171         if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4172
4173         if (needAffiliationFix) {
4174             if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4175             cleanupRecentTasksLocked(task.userId);
4176         }
4177     }
4178
4179     /**
4180      * If needed, remove oldest existing entries in recents that are for the same kind
4181      * of task as the given one.
4182      */
4183     int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4184         int N = mRecentTasks.size();
4185         final Intent intent = task.intent;
4186         final boolean document = intent != null && intent.isDocument();
4187
4188         int maxRecents = task.maxRecents - 1;
4189         for (int i=0; i<N; i++) {
4190             final TaskRecord tr = mRecentTasks.get(i);
4191             if (task != tr) {
4192                 if (task.userId != tr.userId) {
4193                     continue;
4194                 }
4195                 if (i > MAX_RECENT_BITMAPS) {
4196                     tr.freeLastThumbnail();
4197                 }
4198                 final Intent trIntent = tr.intent;
4199                 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4200                     (intent == null || !intent.filterEquals(trIntent))) {
4201                     continue;
4202                 }
4203                 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4204                 if (document && trIsDocument) {
4205                     // These are the same document activity (not necessarily the same doc).
4206                     if (maxRecents > 0) {
4207                         --maxRecents;
4208                         continue;
4209                     }
4210                     // Hit the maximum number of documents for this task. Fall through
4211                     // and remove this document from recents.
4212                 } else if (document || trIsDocument) {
4213                     // Only one of these is a document. Not the droid we're looking for.
4214                     continue;
4215                 }
4216             }
4217
4218             if (!doTrim) {
4219                 // If the caller is not actually asking for a trim, just tell them we reached
4220                 // a point where the trim would happen.
4221                 return i;
4222             }
4223
4224             // Either task and tr are the same or, their affinities match or their intents match
4225             // and neither of them is a document, or they are documents using the same activity
4226             // and their maxRecents has been reached.
4227             tr.disposeThumbnail();
4228             mRecentTasks.remove(i);
4229             if (task != tr) {
4230                 tr.removedFromRecents();
4231             }
4232             i--;
4233             N--;
4234             if (task.intent == null) {
4235                 // If the new recent task we are adding is not fully
4236                 // specified, then replace it with the existing recent task.
4237                 task = tr;
4238             }
4239             notifyTaskPersisterLocked(tr, false);
4240         }
4241
4242         return -1;
4243     }
4244
4245     @Override
4246     public void reportActivityFullyDrawn(IBinder token) {
4247         synchronized (this) {
4248             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4249             if (r == null) {
4250                 return;
4251             }
4252             r.reportFullyDrawnLocked();
4253         }
4254     }
4255
4256     @Override
4257     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4258         synchronized (this) {
4259             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4260             if (r == null) {
4261                 return;
4262             }
4263             final long origId = Binder.clearCallingIdentity();
4264             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4265             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4266                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4267             if (config != null) {
4268                 r.frozenBeforeDestroy = true;
4269                 if (!updateConfigurationLocked(config, r, false, false)) {
4270                     mStackSupervisor.resumeTopActivitiesLocked();
4271                 }
4272             }
4273             Binder.restoreCallingIdentity(origId);
4274         }
4275     }
4276
4277     @Override
4278     public int getRequestedOrientation(IBinder token) {
4279         synchronized (this) {
4280             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4281             if (r == null) {
4282                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4283             }
4284             return mWindowManager.getAppOrientation(r.appToken);
4285         }
4286     }
4287
4288     /**
4289      * This is the internal entry point for handling Activity.finish().
4290      *
4291      * @param token The Binder token referencing the Activity we want to finish.
4292      * @param resultCode Result code, if any, from this Activity.
4293      * @param resultData Result data (Intent), if any, from this Activity.
4294      * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4295      *            the root Activity in the task.
4296      *
4297      * @return Returns true if the activity successfully finished, or false if it is still running.
4298      */
4299     @Override
4300     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4301             boolean finishTask) {
4302         // Refuse possible leaked file descriptors
4303         if (resultData != null && resultData.hasFileDescriptors() == true) {
4304             throw new IllegalArgumentException("File descriptors passed in Intent");
4305         }
4306
4307         synchronized(this) {
4308             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4309             if (r == null) {
4310                 return true;
4311             }
4312             // Keep track of the root activity of the task before we finish it
4313             TaskRecord tr = r.task;
4314             ActivityRecord rootR = tr.getRootActivity();
4315             if (rootR == null) {
4316                 Slog.w(TAG, "Finishing task with all activities already finished");
4317             }
4318             // Do not allow task to finish in Lock Task mode.
4319             if (tr == mStackSupervisor.mLockTaskModeTask) {
4320                 if (rootR == r) {
4321                     Slog.i(TAG, "Not finishing task in lock task mode");
4322                     mStackSupervisor.showLockTaskToast();
4323                     return false;
4324                 }
4325             }
4326             if (mController != null) {
4327                 // Find the first activity that is not finishing.
4328                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4329                 if (next != null) {
4330                     // ask watcher if this is allowed
4331                     boolean resumeOK = true;
4332                     try {
4333                         resumeOK = mController.activityResuming(next.packageName);
4334                     } catch (RemoteException e) {
4335                         mController = null;
4336                         Watchdog.getInstance().setActivityController(null);
4337                     }
4338
4339                     if (!resumeOK) {
4340                         Slog.i(TAG, "Not finishing activity because controller resumed");
4341                         return false;
4342                     }
4343                 }
4344             }
4345             final long origId = Binder.clearCallingIdentity();
4346             try {
4347                 boolean res;
4348                 if (finishTask && r == rootR) {
4349                     // If requested, remove the task that is associated to this activity only if it
4350                     // was the root activity in the task. The result code and data is ignored
4351                     // because we don't support returning them across task boundaries.
4352                     res = removeTaskByIdLocked(tr.taskId, false);
4353                     if (!res) {
4354                         Slog.i(TAG, "Removing task failed to finish activity");
4355                     }
4356                 } else {
4357                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4358                             resultData, "app-request", true);
4359                     if (!res) {
4360                         Slog.i(TAG, "Failed to finish by app-request");
4361                     }
4362                 }
4363                 return res;
4364             } finally {
4365                 Binder.restoreCallingIdentity(origId);
4366             }
4367         }
4368     }
4369
4370     @Override
4371     public final void finishHeavyWeightApp() {
4372         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4373                 != PackageManager.PERMISSION_GRANTED) {
4374             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4375                     + Binder.getCallingPid()
4376                     + ", uid=" + Binder.getCallingUid()
4377                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4378             Slog.w(TAG, msg);
4379             throw new SecurityException(msg);
4380         }
4381
4382         synchronized(this) {
4383             if (mHeavyWeightProcess == null) {
4384                 return;
4385             }
4386
4387             ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4388                     mHeavyWeightProcess.activities);
4389             for (int i=0; i<activities.size(); i++) {
4390                 ActivityRecord r = activities.get(i);
4391                 if (!r.finishing) {
4392                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4393                             null, "finish-heavy", true);
4394                 }
4395             }
4396
4397             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4398                     mHeavyWeightProcess.userId, 0));
4399             mHeavyWeightProcess = null;
4400         }
4401     }
4402
4403     @Override
4404     public void crashApplication(int uid, int initialPid, String packageName,
4405             String message) {
4406         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4407                 != PackageManager.PERMISSION_GRANTED) {
4408             String msg = "Permission Denial: crashApplication() from pid="
4409                     + Binder.getCallingPid()
4410                     + ", uid=" + Binder.getCallingUid()
4411                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4412             Slog.w(TAG, msg);
4413             throw new SecurityException(msg);
4414         }
4415
4416         synchronized(this) {
4417             ProcessRecord proc = null;
4418
4419             // Figure out which process to kill.  We don't trust that initialPid
4420             // still has any relation to current pids, so must scan through the
4421             // list.
4422             synchronized (mPidsSelfLocked) {
4423                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4424                     ProcessRecord p = mPidsSelfLocked.valueAt(i);
4425                     if (p.uid != uid) {
4426                         continue;
4427                     }
4428                     if (p.pid == initialPid) {
4429                         proc = p;
4430                         break;
4431                     }
4432                     if (p.pkgList.containsKey(packageName)) {
4433                         proc = p;
4434                     }
4435                 }
4436             }
4437
4438             if (proc == null) {
4439                 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4440                         + " initialPid=" + initialPid
4441                         + " packageName=" + packageName);
4442                 return;
4443             }
4444
4445             if (proc.thread != null) {
4446                 if (proc.pid == Process.myPid()) {
4447                     Log.w(TAG, "crashApplication: trying to crash self!");
4448                     return;
4449                 }
4450                 long ident = Binder.clearCallingIdentity();
4451                 try {
4452                     proc.thread.scheduleCrash(message);
4453                 } catch (RemoteException e) {
4454                 }
4455                 Binder.restoreCallingIdentity(ident);
4456             }
4457         }
4458     }
4459
4460     @Override
4461     public final void finishSubActivity(IBinder token, String resultWho,
4462             int requestCode) {
4463         synchronized(this) {
4464             final long origId = Binder.clearCallingIdentity();
4465             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4466             if (r != null) {
4467                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4468             }
4469             Binder.restoreCallingIdentity(origId);
4470         }
4471     }
4472
4473     @Override
4474     public boolean finishActivityAffinity(IBinder token) {
4475         synchronized(this) {
4476             final long origId = Binder.clearCallingIdentity();
4477             try {
4478                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4479
4480                 ActivityRecord rootR = r.task.getRootActivity();
4481                 // Do not allow task to finish in Lock Task mode.
4482                 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4483                     if (rootR == r) {
4484                         mStackSupervisor.showLockTaskToast();
4485                         return false;
4486                     }
4487                 }
4488                 boolean res = false;
4489                 if (r != null) {
4490                     res = r.task.stack.finishActivityAffinityLocked(r);
4491                 }
4492                 return res;
4493             } finally {
4494                 Binder.restoreCallingIdentity(origId);
4495             }
4496         }
4497     }
4498
4499     @Override
4500     public void finishVoiceTask(IVoiceInteractionSession session) {
4501         synchronized(this) {
4502             final long origId = Binder.clearCallingIdentity();
4503             try {
4504                 mStackSupervisor.finishVoiceTask(session);
4505             } finally {
4506                 Binder.restoreCallingIdentity(origId);
4507             }
4508         }
4509
4510     }
4511
4512     @Override
4513     public boolean releaseActivityInstance(IBinder token) {
4514         synchronized(this) {
4515             final long origId = Binder.clearCallingIdentity();
4516             try {
4517                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4518                 if (r.task == null || r.task.stack == null) {
4519                     return false;
4520                 }
4521                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4522             } finally {
4523                 Binder.restoreCallingIdentity(origId);
4524             }
4525         }
4526     }
4527
4528     @Override
4529     public void releaseSomeActivities(IApplicationThread appInt) {
4530         synchronized(this) {
4531             final long origId = Binder.clearCallingIdentity();
4532             try {
4533                 ProcessRecord app = getRecordForAppLocked(appInt);
4534                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4535             } finally {
4536                 Binder.restoreCallingIdentity(origId);
4537             }
4538         }
4539     }
4540
4541     @Override
4542     public boolean willActivityBeVisible(IBinder token) {
4543         synchronized(this) {
4544             ActivityStack stack = ActivityRecord.getStackLocked(token);
4545             if (stack != null) {
4546                 return stack.willActivityBeVisibleLocked(token);
4547             }
4548             return false;
4549         }
4550     }
4551
4552     @Override
4553     public void overridePendingTransition(IBinder token, String packageName,
4554             int enterAnim, int exitAnim) {
4555         synchronized(this) {
4556             ActivityRecord self = ActivityRecord.isInStackLocked(token);
4557             if (self == null) {
4558                 return;
4559             }
4560
4561             final long origId = Binder.clearCallingIdentity();
4562
4563             if (self.state == ActivityState.RESUMED
4564                     || self.state == ActivityState.PAUSING) {
4565                 mWindowManager.overridePendingAppTransition(packageName,
4566                         enterAnim, exitAnim, null);
4567             }
4568
4569             Binder.restoreCallingIdentity(origId);
4570         }
4571     }
4572
4573     /**
4574      * Main function for removing an existing process from the activity manager
4575      * as a result of that process going away.  Clears out all connections
4576      * to the process.
4577      */
4578     private final void handleAppDiedLocked(ProcessRecord app,
4579             boolean restarting, boolean allowRestart) {
4580         int pid = app.pid;
4581         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4582                 false /*replacingPid*/);
4583         if (!kept && !restarting) {
4584             removeLruProcessLocked(app);
4585             if (pid > 0) {
4586                 ProcessList.remove(pid);
4587             }
4588         }
4589
4590         if (mProfileProc == app) {
4591             clearProfilerLocked();
4592         }
4593
4594         // Remove this application's activities from active lists.
4595         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4596
4597         app.activities.clear();
4598
4599         if (app.instrumentationClass != null) {
4600             Slog.w(TAG, "Crash of app " + app.processName
4601                   + " running instrumentation " + app.instrumentationClass);
4602             Bundle info = new Bundle();
4603             info.putString("shortMsg", "Process crashed.");
4604             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4605         }
4606
4607         if (!restarting) {
4608             if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4609                 // If there was nothing to resume, and we are not already
4610                 // restarting this process, but there is a visible activity that
4611                 // is hosted by the process...  then make sure all visible
4612                 // activities are running, taking care of restarting this
4613                 // process.
4614                 if (hasVisibleActivities) {
4615                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4616                 }
4617             }
4618         }
4619     }
4620
4621     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4622         IBinder threadBinder = thread.asBinder();
4623         // Find the application record.
4624         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4625             ProcessRecord rec = mLruProcesses.get(i);
4626             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4627                 return i;
4628             }
4629         }
4630         return -1;
4631     }
4632
4633     final ProcessRecord getRecordForAppLocked(
4634             IApplicationThread thread) {
4635         if (thread == null) {
4636             return null;
4637         }
4638
4639         int appIndex = getLRURecordIndexForAppLocked(thread);
4640         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4641     }
4642
4643     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4644         // If there are no longer any background processes running,
4645         // and the app that died was not running instrumentation,
4646         // then tell everyone we are now low on memory.
4647         boolean haveBg = false;
4648         for (int i=mLruProcesses.size()-1; i>=0; i--) {
4649             ProcessRecord rec = mLruProcesses.get(i);
4650             if (rec.thread != null
4651                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4652                 haveBg = true;
4653                 break;
4654             }
4655         }
4656
4657         if (!haveBg) {
4658             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4659             if (doReport) {
4660                 long now = SystemClock.uptimeMillis();
4661                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4662                     doReport = false;
4663                 } else {
4664                     mLastMemUsageReportTime = now;
4665                 }
4666             }
4667             final ArrayList<ProcessMemInfo> memInfos
4668                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4669             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4670             long now = SystemClock.uptimeMillis();
4671             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4672                 ProcessRecord rec = mLruProcesses.get(i);
4673                 if (rec == dyingProc || rec.thread == null) {
4674                     continue;
4675                 }
4676                 if (doReport) {
4677                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4678                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
4679                 }
4680                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4681                     // The low memory report is overriding any current
4682                     // state for a GC request.  Make sure to do
4683                     // heavy/important/visible/foreground processes first.
4684                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4685                         rec.lastRequestedGc = 0;
4686                     } else {
4687                         rec.lastRequestedGc = rec.lastLowMemory;
4688                     }
4689                     rec.reportLowMemory = true;
4690                     rec.lastLowMemory = now;
4691                     mProcessesToGc.remove(rec);
4692                     addProcessToGcListLocked(rec);
4693                 }
4694             }
4695             if (doReport) {
4696                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4697                 mHandler.sendMessage(msg);
4698             }
4699             scheduleAppGcsLocked();
4700         }
4701     }
4702
4703     final void appDiedLocked(ProcessRecord app) {
4704        appDiedLocked(app, app.pid, app.thread);
4705     }
4706
4707     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4708         // First check if this ProcessRecord is actually active for the pid.
4709         synchronized (mPidsSelfLocked) {
4710             ProcessRecord curProc = mPidsSelfLocked.get(pid);
4711             if (curProc != app) {
4712                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4713                 return;
4714             }
4715         }
4716
4717         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4718         synchronized (stats) {
4719             stats.noteProcessDiedLocked(app.info.uid, pid);
4720         }
4721
4722         if (!app.killed) {
4723             Process.killProcessQuiet(pid);
4724             Process.killProcessGroup(app.uid, pid);
4725             app.killed = true;
4726         }
4727
4728         // Clean up already done if the process has been re-started.
4729         if (app.pid == pid && app.thread != null &&
4730                 app.thread.asBinder() == thread.asBinder()) {
4731             boolean doLowMem = app.instrumentationClass == null;
4732             boolean doOomAdj = doLowMem;
4733             if (!app.killedByAm) {
4734                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4735                         + ") has died");
4736                 mAllowLowerMemLevel = true;
4737             } else {
4738                 // Note that we always want to do oom adj to update our state with the
4739                 // new number of procs.
4740                 mAllowLowerMemLevel = false;
4741                 doLowMem = false;
4742             }
4743             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4744             if (DEBUG_CLEANUP) Slog.v(
4745                 TAG, "Dying app: " + app + ", pid: " + pid
4746                 + ", thread: " + thread.asBinder());
4747             handleAppDiedLocked(app, false, true);
4748
4749             if (doOomAdj) {
4750                 updateOomAdjLocked();
4751             }
4752             if (doLowMem) {
4753                 doLowMemReportIfNeededLocked(app);
4754             }
4755         } else if (app.pid != pid) {
4756             // A new process has already been started.
4757             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4758                     + ") has died and restarted (pid " + app.pid + ").");
4759             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4760         } else if (DEBUG_PROCESSES) {
4761             Slog.d(TAG, "Received spurious death notification for thread "
4762                     + thread.asBinder());
4763         }
4764     }
4765
4766     /**
4767      * If a stack trace dump file is configured, dump process stack traces.
4768      * @param clearTraces causes the dump file to be erased prior to the new
4769      *    traces being written, if true; when false, the new traces will be
4770      *    appended to any existing file content.
4771      * @param firstPids of dalvik VM processes to dump stack traces for first
4772      * @param lastPids of dalvik VM processes to dump stack traces for last
4773      * @param nativeProcs optional list of native process names to dump stack crawls
4774      * @return file containing stack traces, or null if no dump file is configured
4775      */
4776     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4777             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4778         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4779         if (tracesPath == null || tracesPath.length() == 0) {
4780             return null;
4781         }
4782
4783         File tracesFile = new File(tracesPath);
4784         try {
4785             File tracesDir = tracesFile.getParentFile();
4786             if (!tracesDir.exists()) {
4787                 tracesDir.mkdirs();
4788                 if (!SELinux.restorecon(tracesDir)) {
4789                     return null;
4790                 }
4791             }
4792             FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4793
4794             if (clearTraces && tracesFile.exists()) tracesFile.delete();
4795             tracesFile.createNewFile();
4796             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4797         } catch (IOException e) {
4798             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4799             return null;
4800         }
4801
4802         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4803         return tracesFile;
4804     }
4805
4806     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4807             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4808         // Use a FileObserver to detect when traces finish writing.
4809         // The order of traces is considered important to maintain for legibility.
4810         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4811             @Override
4812             public synchronized void onEvent(int event, String path) { notify(); }
4813         };
4814
4815         try {
4816             observer.startWatching();
4817
4818             // First collect all of the stacks of the most important pids.
4819             if (firstPids != null) {
4820                 try {
4821                     int num = firstPids.size();
4822                     for (int i = 0; i < num; i++) {
4823                         synchronized (observer) {
4824                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4825                             observer.wait(200);  // Wait for write-close, give up after 200msec
4826                         }
4827                     }
4828                 } catch (InterruptedException e) {
4829                     Slog.wtf(TAG, e);
4830                 }
4831             }
4832
4833             // Next collect the stacks of the native pids
4834             if (nativeProcs != null) {
4835                 int[] pids = Process.getPidsForCommands(nativeProcs);
4836                 if (pids != null) {
4837                     for (int pid : pids) {
4838                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4839                     }
4840                 }
4841             }
4842
4843             // Lastly, measure CPU usage.
4844             if (processCpuTracker != null) {
4845                 processCpuTracker.init();
4846                 System.gc();
4847                 processCpuTracker.update();
4848                 try {
4849                     synchronized (processCpuTracker) {
4850                         processCpuTracker.wait(500); // measure over 1/2 second.
4851                     }
4852                 } catch (InterruptedException e) {
4853                 }
4854                 processCpuTracker.update();
4855
4856                 // We'll take the stack crawls of just the top apps using CPU.
4857                 final int N = processCpuTracker.countWorkingStats();
4858                 int numProcs = 0;
4859                 for (int i=0; i<N && numProcs<5; i++) {
4860                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4861                     if (lastPids.indexOfKey(stats.pid) >= 0) {
4862                         numProcs++;
4863                         try {
4864                             synchronized (observer) {
4865                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4866                                 observer.wait(200);  // Wait for write-close, give up after 200msec
4867                             }
4868                         } catch (InterruptedException e) {
4869                             Slog.wtf(TAG, e);
4870                         }
4871
4872                     }
4873                 }
4874             }
4875         } finally {
4876             observer.stopWatching();
4877         }
4878     }
4879
4880     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4881         if (true || IS_USER_BUILD) {
4882             return;
4883         }
4884         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4885         if (tracesPath == null || tracesPath.length() == 0) {
4886             return;
4887         }
4888
4889         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4890         StrictMode.allowThreadDiskWrites();
4891         try {
4892             final File tracesFile = new File(tracesPath);
4893             final File tracesDir = tracesFile.getParentFile();
4894             final File tracesTmp = new File(tracesDir, "__tmp__");
4895             try {
4896                 if (!tracesDir.exists()) {
4897                     tracesDir.mkdirs();
4898                     if (!SELinux.restorecon(tracesDir.getPath())) {
4899                         return;
4900                     }
4901                 }
4902                 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4903
4904                 if (tracesFile.exists()) {
4905                     tracesTmp.delete();
4906                     tracesFile.renameTo(tracesTmp);
4907                 }
4908                 StringBuilder sb = new StringBuilder();
4909                 Time tobj = new Time();
4910                 tobj.set(System.currentTimeMillis());
4911                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4912                 sb.append(": ");
4913                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4914                 sb.append(" since ");
4915                 sb.append(msg);
4916                 FileOutputStream fos = new FileOutputStream(tracesFile);
4917                 fos.write(sb.toString().getBytes());
4918                 if (app == null) {
4919                     fos.write("\n*** No application process!".getBytes());
4920                 }
4921                 fos.close();
4922                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4923             } catch (IOException e) {
4924                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4925                 return;
4926             }
4927
4928             if (app != null) {
4929                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4930                 firstPids.add(app.pid);
4931                 dumpStackTraces(tracesPath, firstPids, null, null, null);
4932             }
4933
4934             File lastTracesFile = null;
4935             File curTracesFile = null;
4936             for (int i=9; i>=0; i--) {
4937                 String name = String.format(Locale.US, "slow%02d.txt", i);
4938                 curTracesFile = new File(tracesDir, name);
4939                 if (curTracesFile.exists()) {
4940                     if (lastTracesFile != null) {
4941                         curTracesFile.renameTo(lastTracesFile);
4942                     } else {
4943                         curTracesFile.delete();
4944                     }
4945                 }
4946                 lastTracesFile = curTracesFile;
4947             }
4948             tracesFile.renameTo(curTracesFile);
4949             if (tracesTmp.exists()) {
4950                 tracesTmp.renameTo(tracesFile);
4951             }
4952         } finally {
4953             StrictMode.setThreadPolicy(oldPolicy);
4954         }
4955     }
4956
4957     final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4958             ActivityRecord parent, boolean aboveSystem, final String annotation) {
4959         ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4960         SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4961
4962         if (mController != null) {
4963             try {
4964                 // 0 == continue, -1 = kill process immediately
4965                 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4966                 if (res < 0 && app.pid != MY_PID) {
4967                     app.kill("anr", true);
4968                 }
4969             } catch (RemoteException e) {
4970                 mController = null;
4971                 Watchdog.getInstance().setActivityController(null);
4972             }
4973         }
4974
4975         long anrTime = SystemClock.uptimeMillis();
4976         if (MONITOR_CPU_USAGE) {
4977             updateCpuStatsNow();
4978         }
4979
4980         synchronized (this) {
4981             // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4982             if (mShuttingDown) {
4983                 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4984                 return;
4985             } else if (app.notResponding) {
4986                 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4987                 return;
4988             } else if (app.crashing) {
4989                 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4990                 return;
4991             }
4992
4993             // In case we come through here for the same app before completing
4994             // this one, mark as anring now so we will bail out.
4995             app.notResponding = true;
4996
4997             // Log the ANR to the event log.
4998             EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4999                     app.processName, app.info.flags, annotation);
5000
5001             // Dump thread traces as quickly as we can, starting with "interesting" processes.
5002             firstPids.add(app.pid);
5003
5004             int parentPid = app.pid;
5005             if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5006             if (parentPid != app.pid) firstPids.add(parentPid);
5007
5008             if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5009
5010             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5011                 ProcessRecord r = mLruProcesses.get(i);
5012                 if (r != null && r.thread != null) {
5013                     int pid = r.pid;
5014                     if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5015                         if (r.persistent) {
5016                             firstPids.add(pid);
5017                         } else {
5018                             lastPids.put(pid, Boolean.TRUE);
5019                         }
5020                     }
5021                 }
5022             }
5023         }
5024
5025         // Log the ANR to the main log.
5026         StringBuilder info = new StringBuilder();
5027         info.setLength(0);
5028         info.append("ANR in ").append(app.processName);
5029         if (activity != null && activity.shortComponentName != null) {
5030             info.append(" (").append(activity.shortComponentName).append(")");
5031         }
5032         info.append("\n");
5033         info.append("PID: ").append(app.pid).append("\n");
5034         if (annotation != null) {
5035             info.append("Reason: ").append(annotation).append("\n");
5036         }
5037         if (parent != null && parent != activity) {
5038             info.append("Parent: ").append(parent.shortComponentName).append("\n");
5039         }
5040
5041         final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5042
5043         File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5044                 NATIVE_STACKS_OF_INTEREST);
5045
5046         String cpuInfo = null;
5047         if (MONITOR_CPU_USAGE) {
5048             updateCpuStatsNow();
5049             synchronized (mProcessCpuTracker) {
5050                 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5051             }
5052             info.append(processCpuTracker.printCurrentLoad());
5053             info.append(cpuInfo);
5054         }
5055
5056         info.append(processCpuTracker.printCurrentState(anrTime));
5057
5058         Slog.e(TAG, info.toString());
5059         if (tracesFile == null) {
5060             // There is no trace file, so dump (only) the alleged culprit's threads to the log
5061             Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5062         }
5063
5064         addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5065                 cpuInfo, tracesFile, null);
5066
5067         if (mController != null) {
5068             try {
5069                 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5070                 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5071                 if (res != 0) {
5072                     if (res < 0 && app.pid != MY_PID) {
5073                         app.kill("anr", true);
5074                     } else {
5075                         synchronized (this) {
5076                             mServices.scheduleServiceTimeoutLocked(app);
5077                         }
5078                     }
5079                     return;
5080                 }
5081             } catch (RemoteException e) {
5082                 mController = null;
5083                 Watchdog.getInstance().setActivityController(null);
5084             }
5085         }
5086
5087         // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5088         boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5089                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5090
5091         synchronized (this) {
5092             mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5093
5094             if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5095                 app.kill("bg anr", true);
5096                 return;
5097             }
5098
5099             // Set the app's notResponding state, and look up the errorReportReceiver
5100             makeAppNotRespondingLocked(app,
5101                     activity != null ? activity.shortComponentName : null,
5102                     annotation != null ? "ANR " + annotation : "ANR",
5103                     info.toString());
5104
5105             // Bring up the infamous App Not Responding dialog
5106             Message msg = Message.obtain();
5107             HashMap<String, Object> map = new HashMap<String, Object>();
5108             msg.what = SHOW_NOT_RESPONDING_MSG;
5109             msg.obj = map;
5110             msg.arg1 = aboveSystem ? 1 : 0;
5111             map.put("app", app);
5112             if (activity != null) {
5113                 map.put("activity", activity);
5114             }
5115
5116             mHandler.sendMessage(msg);
5117         }
5118     }
5119
5120     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5121         if (!mLaunchWarningShown) {
5122             mLaunchWarningShown = true;
5123             mHandler.post(new Runnable() {
5124                 @Override
5125                 public void run() {
5126                     synchronized (ActivityManagerService.this) {
5127                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5128                         d.show();
5129                         mHandler.postDelayed(new Runnable() {
5130                             @Override
5131                             public void run() {
5132                                 synchronized (ActivityManagerService.this) {
5133                                     d.dismiss();
5134                                     mLaunchWarningShown = false;
5135                                 }
5136                             }
5137                         }, 4000);
5138                     }
5139                 }
5140             });
5141         }
5142     }
5143
5144     @Override
5145     public boolean clearApplicationUserData(final String packageName,
5146             final IPackageDataObserver observer, int userId) {
5147         enforceNotIsolatedCaller("clearApplicationUserData");
5148         int uid = Binder.getCallingUid();
5149         int pid = Binder.getCallingPid();
5150         userId = handleIncomingUser(pid, uid,
5151                 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5152         long callingId = Binder.clearCallingIdentity();
5153         try {
5154             IPackageManager pm = AppGlobals.getPackageManager();
5155             int pkgUid = -1;
5156             synchronized(this) {
5157                 try {
5158                     pkgUid = pm.getPackageUid(packageName, userId);
5159                 } catch (RemoteException e) {
5160                 }
5161                 if (pkgUid == -1) {
5162                     Slog.w(TAG, "Invalid packageName: " + packageName);
5163                     if (observer != null) {
5164                         try {
5165                             observer.onRemoveCompleted(packageName, false);
5166                         } catch (RemoteException e) {
5167                             Slog.i(TAG, "Observer no longer exists.");
5168                         }
5169                     }
5170                     return false;
5171                 }
5172                 if (uid == pkgUid || checkComponentPermission(
5173                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5174                         pid, uid, -1, true)
5175                         == PackageManager.PERMISSION_GRANTED) {
5176                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5177                 } else {
5178                     throw new SecurityException("PID " + pid + " does not have permission "
5179                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5180                                     + " of package " + packageName);
5181                 }
5182
5183                 // Remove all tasks match the cleared application package and user
5184                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5185                     final TaskRecord tr = mRecentTasks.get(i);
5186                     final String taskPackageName =
5187                             tr.getBaseIntent().getComponent().getPackageName();
5188                     if (tr.userId != userId) continue;
5189                     if (!taskPackageName.equals(packageName)) continue;
5190                     removeTaskByIdLocked(tr.taskId, false);
5191                 }
5192             }
5193
5194             try {
5195                 // Clear application user data
5196                 pm.clearApplicationUserData(packageName, observer, userId);
5197
5198                 synchronized(this) {
5199                     // Remove all permissions granted from/to this package
5200                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5201                 }
5202
5203                 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5204                         Uri.fromParts("package", packageName, null));
5205                 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5206                 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5207                         null, null, 0, null, null, null, false, false, userId);
5208             } catch (RemoteException e) {
5209             }
5210         } finally {
5211             Binder.restoreCallingIdentity(callingId);
5212         }
5213         return true;
5214     }
5215
5216     @Override
5217     public void killBackgroundProcesses(final String packageName, int userId) {
5218         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5219                 != PackageManager.PERMISSION_GRANTED &&
5220                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5221                         != PackageManager.PERMISSION_GRANTED) {
5222             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5223                     + Binder.getCallingPid()
5224                     + ", uid=" + Binder.getCallingUid()
5225                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5226             Slog.w(TAG, msg);
5227             throw new SecurityException(msg);
5228         }
5229
5230         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5231                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5232         long callingId = Binder.clearCallingIdentity();
5233         try {
5234             IPackageManager pm = AppGlobals.getPackageManager();
5235             synchronized(this) {
5236                 int appId = -1;
5237                 try {
5238                     appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5239                 } catch (RemoteException e) {
5240                 }
5241                 if (appId == -1) {
5242                     Slog.w(TAG, "Invalid packageName: " + packageName);
5243                     return;
5244                 }
5245                 killPackageProcessesLocked(packageName, appId, userId,
5246                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5247             }
5248         } finally {
5249             Binder.restoreCallingIdentity(callingId);
5250         }
5251     }
5252
5253     @Override
5254     public void killAllBackgroundProcesses() {
5255         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5256                 != PackageManager.PERMISSION_GRANTED) {
5257             String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5258                     + Binder.getCallingPid()
5259                     + ", uid=" + Binder.getCallingUid()
5260                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5261             Slog.w(TAG, msg);
5262             throw new SecurityException(msg);
5263         }
5264
5265         long callingId = Binder.clearCallingIdentity();
5266         try {
5267             synchronized(this) {
5268                 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5269                 final int NP = mProcessNames.getMap().size();
5270                 for (int ip=0; ip<NP; ip++) {
5271                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5272                     final int NA = apps.size();
5273                     for (int ia=0; ia<NA; ia++) {
5274                         ProcessRecord app = apps.valueAt(ia);
5275                         if (app.persistent) {
5276                             // we don't kill persistent processes
5277                             continue;
5278                         }
5279                         if (app.removed) {
5280                             procs.add(app);
5281                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5282                             app.removed = true;
5283                             procs.add(app);
5284                         }
5285                     }
5286                 }
5287
5288                 int N = procs.size();
5289                 for (int i=0; i<N; i++) {
5290                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5291                 }
5292                 mAllowLowerMemLevel = true;
5293                 updateOomAdjLocked();
5294                 doLowMemReportIfNeededLocked(null);
5295             }
5296         } finally {
5297             Binder.restoreCallingIdentity(callingId);
5298         }
5299     }
5300
5301     @Override
5302     public void forceStopPackage(final String packageName, int userId) {
5303         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5304                 != PackageManager.PERMISSION_GRANTED) {
5305             String msg = "Permission Denial: forceStopPackage() from pid="
5306                     + Binder.getCallingPid()
5307                     + ", uid=" + Binder.getCallingUid()
5308                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5309             Slog.w(TAG, msg);
5310             throw new SecurityException(msg);
5311         }
5312         final int callingPid = Binder.getCallingPid();
5313         userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5314                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5315         long callingId = Binder.clearCallingIdentity();
5316         try {
5317             IPackageManager pm = AppGlobals.getPackageManager();
5318             synchronized(this) {
5319                 int[] users = userId == UserHandle.USER_ALL
5320                         ? getUsersLocked() : new int[] { userId };
5321                 for (int user : users) {
5322                     int pkgUid = -1;
5323                     try {
5324                         pkgUid = pm.getPackageUid(packageName, user);
5325                     } catch (RemoteException e) {
5326                     }
5327                     if (pkgUid == -1) {
5328                         Slog.w(TAG, "Invalid packageName: " + packageName);
5329                         continue;
5330                     }
5331                     try {
5332                         pm.setPackageStoppedState(packageName, true, user);
5333                     } catch (RemoteException e) {
5334                     } catch (IllegalArgumentException e) {
5335                         Slog.w(TAG, "Failed trying to unstop package "
5336                                 + packageName + ": " + e);
5337                     }
5338                     if (isUserRunningLocked(user, false)) {
5339                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5340                     }
5341                 }
5342             }
5343         } finally {
5344             Binder.restoreCallingIdentity(callingId);
5345         }
5346     }
5347
5348     @Override
5349     public void addPackageDependency(String packageName) {
5350         synchronized (this) {
5351             int callingPid = Binder.getCallingPid();
5352             if (callingPid == Process.myPid()) {
5353                 //  Yeah, um, no.
5354                 return;
5355             }
5356             ProcessRecord proc;
5357             synchronized (mPidsSelfLocked) {
5358                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5359             }
5360             if (proc != null) {
5361                 if (proc.pkgDeps == null) {
5362                     proc.pkgDeps = new ArraySet<String>(1);
5363                 }
5364                 proc.pkgDeps.add(packageName);
5365             }
5366         }
5367     }
5368
5369     /*
5370      * The pkg name and app id have to be specified.
5371      */
5372     @Override
5373     public void killApplicationWithAppId(String pkg, int appid, String reason) {
5374         if (pkg == null) {
5375             return;
5376         }
5377         // Make sure the uid is valid.
5378         if (appid < 0) {
5379             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5380             return;
5381         }
5382         int callerUid = Binder.getCallingUid();
5383         // Only the system server can kill an application
5384         if (callerUid == Process.SYSTEM_UID) {
5385             // Post an aysnc message to kill the application
5386             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5387             msg.arg1 = appid;
5388             msg.arg2 = 0;
5389             Bundle bundle = new Bundle();
5390             bundle.putString("pkg", pkg);
5391             bundle.putString("reason", reason);
5392             msg.obj = bundle;
5393             mHandler.sendMessage(msg);
5394         } else {
5395             throw new SecurityException(callerUid + " cannot kill pkg: " +
5396                     pkg);
5397         }
5398     }
5399
5400     @Override
5401     public void closeSystemDialogs(String reason) {
5402         enforceNotIsolatedCaller("closeSystemDialogs");
5403
5404         final int pid = Binder.getCallingPid();
5405         final int uid = Binder.getCallingUid();
5406         final long origId = Binder.clearCallingIdentity();
5407         try {
5408             synchronized (this) {
5409                 // Only allow this from foreground processes, so that background
5410                 // applications can't abuse it to prevent system UI from being shown.
5411                 if (uid >= Process.FIRST_APPLICATION_UID) {
5412                     ProcessRecord proc;
5413                     synchronized (mPidsSelfLocked) {
5414                         proc = mPidsSelfLocked.get(pid);
5415                     }
5416                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5417                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5418                                 + " from background process " + proc);
5419                         return;
5420                     }
5421                 }
5422                 closeSystemDialogsLocked(reason);
5423             }
5424         } finally {
5425             Binder.restoreCallingIdentity(origId);
5426         }
5427     }
5428
5429     void closeSystemDialogsLocked(String reason) {
5430         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5431         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5432                 | Intent.FLAG_RECEIVER_FOREGROUND);
5433         if (reason != null) {
5434             intent.putExtra("reason", reason);
5435         }
5436         mWindowManager.closeSystemDialogs(reason);
5437
5438         mStackSupervisor.closeSystemDialogsLocked();
5439
5440         broadcastIntentLocked(null, null, intent, null,
5441                 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5442                 Process.SYSTEM_UID, UserHandle.USER_ALL);
5443     }
5444
5445     @Override
5446     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5447         enforceNotIsolatedCaller("getProcessMemoryInfo");
5448         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5449         for (int i=pids.length-1; i>=0; i--) {
5450             ProcessRecord proc;
5451             int oomAdj;
5452             synchronized (this) {
5453                 synchronized (mPidsSelfLocked) {
5454                     proc = mPidsSelfLocked.get(pids[i]);
5455                     oomAdj = proc != null ? proc.setAdj : 0;
5456                 }
5457             }
5458             infos[i] = new Debug.MemoryInfo();
5459             Debug.getMemoryInfo(pids[i], infos[i]);
5460             if (proc != null) {
5461                 synchronized (this) {
5462                     if (proc.thread != null && proc.setAdj == oomAdj) {
5463                         // Record this for posterity if the process has been stable.
5464                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5465                                 infos[i].getTotalUss(), false, proc.pkgList);
5466                     }
5467                 }
5468             }
5469         }
5470         return infos;
5471     }
5472
5473     @Override
5474     public long[] getProcessPss(int[] pids) {
5475         enforceNotIsolatedCaller("getProcessPss");
5476         long[] pss = new long[pids.length];
5477         for (int i=pids.length-1; i>=0; i--) {
5478             ProcessRecord proc;
5479             int oomAdj;
5480             synchronized (this) {
5481                 synchronized (mPidsSelfLocked) {
5482                     proc = mPidsSelfLocked.get(pids[i]);
5483                     oomAdj = proc != null ? proc.setAdj : 0;
5484                 }
5485             }
5486             long[] tmpUss = new long[1];
5487             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5488             if (proc != null) {
5489                 synchronized (this) {
5490                     if (proc.thread != null && proc.setAdj == oomAdj) {
5491                         // Record this for posterity if the process has been stable.
5492                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5493                     }
5494                 }
5495             }
5496         }
5497         return pss;
5498     }
5499
5500     @Override
5501     public void killApplicationProcess(String processName, int uid) {
5502         if (processName == null) {
5503             return;
5504         }
5505
5506         int callerUid = Binder.getCallingUid();
5507         // Only the system server can kill an application
5508         if (callerUid == Process.SYSTEM_UID) {
5509             synchronized (this) {
5510                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5511                 if (app != null && app.thread != null) {
5512                     try {
5513                         app.thread.scheduleSuicide();
5514                     } catch (RemoteException e) {
5515                         // If the other end already died, then our work here is done.
5516                     }
5517                 } else {
5518                     Slog.w(TAG, "Process/uid not found attempting kill of "
5519                             + processName + " / " + uid);
5520                 }
5521             }
5522         } else {
5523             throw new SecurityException(callerUid + " cannot kill app process: " +
5524                     processName);
5525         }
5526     }
5527
5528     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5529         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5530                 false, true, false, false, UserHandle.getUserId(uid), reason);
5531         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5532                 Uri.fromParts("package", packageName, null));
5533         if (!mProcessesReady) {
5534             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5535                     | Intent.FLAG_RECEIVER_FOREGROUND);
5536         }
5537         intent.putExtra(Intent.EXTRA_UID, uid);
5538         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5539         broadcastIntentLocked(null, null, intent,
5540                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5541                 false, false,
5542                 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5543     }
5544
5545     private void forceStopUserLocked(int userId, String reason) {
5546         forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5547         Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5548         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5549                 | Intent.FLAG_RECEIVER_FOREGROUND);
5550         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5551         broadcastIntentLocked(null, null, intent,
5552                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5553                 false, false,
5554                 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5555     }
5556
5557     private final boolean killPackageProcessesLocked(String packageName, int appId,
5558             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5559             boolean doit, boolean evenPersistent, String reason) {
5560         ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5561
5562         // Remove all processes this package may have touched: all with the
5563         // same UID (except for the system or root user), and all whose name
5564         // matches the package name.
5565         final int NP = mProcessNames.getMap().size();
5566         for (int ip=0; ip<NP; ip++) {
5567             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5568             final int NA = apps.size();
5569             for (int ia=0; ia<NA; ia++) {
5570                 ProcessRecord app = apps.valueAt(ia);
5571                 if (app.persistent && !evenPersistent) {
5572                     // we don't kill persistent processes
5573                     continue;
5574                 }
5575                 if (app.removed) {
5576                     if (doit) {
5577                         procs.add(app);
5578                     }
5579                     continue;
5580                 }
5581
5582                 // Skip process if it doesn't meet our oom adj requirement.
5583                 if (app.setAdj < minOomAdj) {
5584                     continue;
5585                 }
5586
5587                 // If no package is specified, we call all processes under the
5588                 // give user id.
5589                 if (packageName == null) {
5590                     if (app.userId != userId) {
5591                         continue;
5592                     }
5593                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5594                         continue;
5595                     }
5596                 // Package has been specified, we want to hit all processes
5597                 // that match it.  We need to qualify this by the processes
5598                 // that are running under the specified app and user ID.
5599                 } else {
5600                     final boolean isDep = app.pkgDeps != null
5601                             && app.pkgDeps.contains(packageName);
5602                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5603                         continue;
5604                     }
5605                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5606                         continue;
5607                     }
5608                     if (!app.pkgList.containsKey(packageName) && !isDep) {
5609                         continue;
5610                     }
5611                 }
5612
5613                 // Process has passed all conditions, kill it!
5614                 if (!doit) {
5615                     return true;
5616                 }
5617                 app.removed = true;
5618                 procs.add(app);
5619             }
5620         }
5621
5622         int N = procs.size();
5623         for (int i=0; i<N; i++) {
5624             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5625         }
5626         updateOomAdjLocked();
5627         return N > 0;
5628     }
5629
5630     private final boolean forceStopPackageLocked(String name, int appId,
5631             boolean callerWillRestart, boolean purgeCache, boolean doit,
5632             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5633         int i;
5634         int N;
5635
5636         if (userId == UserHandle.USER_ALL && name == null) {
5637             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5638         }
5639
5640         if (appId < 0 && name != null) {
5641             try {
5642                 appId = UserHandle.getAppId(
5643                         AppGlobals.getPackageManager().getPackageUid(name, 0));
5644             } catch (RemoteException e) {
5645             }
5646         }
5647
5648         if (doit) {
5649             if (name != null) {
5650                 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5651                         + " user=" + userId + ": " + reason);
5652             } else {
5653                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5654             }
5655
5656             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5657             for (int ip=pmap.size()-1; ip>=0; ip--) {
5658                 SparseArray<Long> ba = pmap.valueAt(ip);
5659                 for (i=ba.size()-1; i>=0; i--) {
5660                     boolean remove = false;
5661                     final int entUid = ba.keyAt(i);
5662                     if (name != null) {
5663                         if (userId == UserHandle.USER_ALL) {
5664                             if (UserHandle.getAppId(entUid) == appId) {
5665                                 remove = true;
5666                             }
5667                         } else {
5668                             if (entUid == UserHandle.getUid(userId, appId)) {
5669                                 remove = true;
5670                             }
5671                         }
5672                     } else if (UserHandle.getUserId(entUid) == userId) {
5673                         remove = true;
5674                     }
5675                     if (remove) {
5676                         ba.removeAt(i);
5677                     }
5678                 }
5679                 if (ba.size() == 0) {
5680                     pmap.removeAt(ip);
5681                 }
5682             }
5683         }
5684
5685         boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5686                 -100, callerWillRestart, true, doit, evenPersistent,
5687                 name == null ? ("stop user " + userId) : ("stop " + name));
5688
5689         if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5690             if (!doit) {
5691                 return true;
5692             }
5693             didSomething = true;
5694         }
5695
5696         if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5697             if (!doit) {
5698                 return true;
5699             }
5700             didSomething = true;
5701         }
5702
5703         if (name == null) {
5704             // Remove all sticky broadcasts from this user.
5705             mStickyBroadcasts.remove(userId);
5706         }
5707
5708         ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5709         if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5710                 userId, providers)) {
5711             if (!doit) {
5712                 return true;
5713             }
5714             didSomething = true;
5715         }
5716         N = providers.size();
5717         for (i=0; i<N; i++) {
5718             removeDyingProviderLocked(null, providers.get(i), true);
5719         }
5720
5721         // Remove transient permissions granted from/to this package/user
5722         removeUriPermissionsForPackageLocked(name, userId, false);
5723
5724         if (name == null || uninstalling) {
5725             // Remove pending intents.  For now we only do this when force
5726             // stopping users, because we have some problems when doing this
5727             // for packages -- app widgets are not currently cleaned up for
5728             // such packages, so they can be left with bad pending intents.
5729             if (mIntentSenderRecords.size() > 0) {
5730                 Iterator<WeakReference<PendingIntentRecord>> it
5731                         = mIntentSenderRecords.values().iterator();
5732                 while (it.hasNext()) {
5733                     WeakReference<PendingIntentRecord> wpir = it.next();
5734                     if (wpir == null) {
5735                         it.remove();
5736                         continue;
5737                     }
5738                     PendingIntentRecord pir = wpir.get();
5739                     if (pir == null) {
5740                         it.remove();
5741                         continue;
5742                     }
5743                     if (name == null) {
5744                         // Stopping user, remove all objects for the user.
5745                         if (pir.key.userId != userId) {
5746                             // Not the same user, skip it.
5747                             continue;
5748                         }
5749                     } else {
5750                         if (UserHandle.getAppId(pir.uid) != appId) {
5751                             // Different app id, skip it.
5752                             continue;
5753                         }
5754                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5755                             // Different user, skip it.
5756                             continue;
5757                         }
5758                         if (!pir.key.packageName.equals(name)) {
5759                             // Different package, skip it.
5760                             continue;
5761                         }
5762                     }
5763                     if (!doit) {
5764                         return true;
5765                     }
5766                     didSomething = true;
5767                     it.remove();
5768                     pir.canceled = true;
5769                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5770                         pir.key.activity.pendingResults.remove(pir.ref);
5771                     }
5772                 }
5773             }
5774         }
5775
5776         if (doit) {
5777             if (purgeCache && name != null) {
5778                 AttributeCache ac = AttributeCache.instance();
5779                 if (ac != null) {
5780                     ac.removePackage(name);
5781                 }
5782             }
5783             if (mBooted) {
5784                 mStackSupervisor.resumeTopActivitiesLocked();
5785                 mStackSupervisor.scheduleIdleLocked();
5786             }
5787         }
5788
5789         return didSomething;
5790     }
5791
5792     private final boolean removeProcessLocked(ProcessRecord app,
5793             boolean callerWillRestart, boolean allowRestart, String reason) {
5794         final String name = app.processName;
5795         final int uid = app.uid;
5796         if (DEBUG_PROCESSES) Slog.d(
5797             TAG, "Force removing proc " + app.toShortString() + " (" + name
5798             + "/" + uid + ")");
5799
5800         mProcessNames.remove(name, uid);
5801         mIsolatedProcesses.remove(app.uid);
5802         if (mHeavyWeightProcess == app) {
5803             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5804                     mHeavyWeightProcess.userId, 0));
5805             mHeavyWeightProcess = null;
5806         }
5807         boolean needRestart = false;
5808         if (app.pid > 0 && app.pid != MY_PID) {
5809             int pid = app.pid;
5810             synchronized (mPidsSelfLocked) {
5811                 mPidsSelfLocked.remove(pid);
5812                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5813             }
5814             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5815             if (app.isolated) {
5816                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5817             }
5818             app.kill(reason, true);
5819             handleAppDiedLocked(app, true, allowRestart);
5820             removeLruProcessLocked(app);
5821
5822             if (app.persistent && !app.isolated) {
5823                 if (!callerWillRestart) {
5824                     addAppLocked(app.info, false, null /* ABI override */);
5825                 } else {
5826                     needRestart = true;
5827                 }
5828             }
5829         } else {
5830             mRemovedProcesses.add(app);
5831         }
5832
5833         return needRestart;
5834     }
5835
5836     private final void processStartTimedOutLocked(ProcessRecord app) {
5837         final int pid = app.pid;
5838         boolean gone = false;
5839         synchronized (mPidsSelfLocked) {
5840             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5841             if (knownApp != null && knownApp.thread == null) {
5842                 mPidsSelfLocked.remove(pid);
5843                 gone = true;
5844             }
5845         }
5846
5847         if (gone) {
5848             Slog.w(TAG, "Process " + app + " failed to attach");
5849             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5850                     pid, app.uid, app.processName);
5851             mProcessNames.remove(app.processName, app.uid);
5852             mIsolatedProcesses.remove(app.uid);
5853             if (mHeavyWeightProcess == app) {
5854                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5855                         mHeavyWeightProcess.userId, 0));
5856                 mHeavyWeightProcess = null;
5857             }
5858             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5859             if (app.isolated) {
5860                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5861             }
5862             // Take care of any launching providers waiting for this process.
5863             checkAppInLaunchingProvidersLocked(app, true);
5864             // Take care of any services that are waiting for the process.
5865             mServices.processStartTimedOutLocked(app);
5866             app.kill("start timeout", true);
5867             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5868                 Slog.w(TAG, "Unattached app died before backup, skipping");
5869                 try {
5870                     IBackupManager bm = IBackupManager.Stub.asInterface(
5871                             ServiceManager.getService(Context.BACKUP_SERVICE));
5872                     bm.agentDisconnected(app.info.packageName);
5873                 } catch (RemoteException e) {
5874                     // Can't happen; the backup manager is local
5875                 }
5876             }
5877             if (isPendingBroadcastProcessLocked(pid)) {
5878                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5879                 skipPendingBroadcastLocked(pid);
5880             }
5881         } else {
5882             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5883         }
5884     }
5885
5886     private final boolean attachApplicationLocked(IApplicationThread thread,
5887             int pid) {
5888
5889         // Find the application record that is being attached...  either via
5890         // the pid if we are running in multiple processes, or just pull the
5891         // next app record if we are emulating process with anonymous threads.
5892         ProcessRecord app;
5893         if (pid != MY_PID && pid >= 0) {
5894             synchronized (mPidsSelfLocked) {
5895                 app = mPidsSelfLocked.get(pid);
5896             }
5897         } else {
5898             app = null;
5899         }
5900
5901         if (app == null) {
5902             Slog.w(TAG, "No pending application record for pid " + pid
5903                     + " (IApplicationThread " + thread + "); dropping process");
5904             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5905             if (pid > 0 && pid != MY_PID) {
5906                 Process.killProcessQuiet(pid);
5907                 //TODO: Process.killProcessGroup(app.info.uid, pid);
5908             } else {
5909                 try {
5910                     thread.scheduleExit();
5911                 } catch (Exception e) {
5912                     // Ignore exceptions.
5913                 }
5914             }
5915             return false;
5916         }
5917
5918         // If this application record is still attached to a previous
5919         // process, clean it up now.
5920         if (app.thread != null) {
5921             handleAppDiedLocked(app, true, true);
5922         }
5923
5924         // Tell the process all about itself.
5925
5926         if (localLOGV) Slog.v(
5927                 TAG, "Binding process pid " + pid + " to record " + app);
5928
5929         final String processName = app.processName;
5930         try {
5931             AppDeathRecipient adr = new AppDeathRecipient(
5932                     app, pid, thread);
5933             thread.asBinder().linkToDeath(adr, 0);
5934             app.deathRecipient = adr;
5935         } catch (RemoteException e) {
5936             app.resetPackageList(mProcessStats);
5937             startProcessLocked(app, "link fail", processName);
5938             return false;
5939         }
5940
5941         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5942
5943         app.makeActive(thread, mProcessStats);
5944         app.curAdj = app.setAdj = -100;
5945         app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5946         app.forcingToForeground = null;
5947         updateProcessForegroundLocked(app, false, false);
5948         app.hasShownUi = false;
5949         app.debugging = false;
5950         app.cached = false;
5951         app.killedByAm = false;
5952
5953         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5954
5955         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5956         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5957
5958         if (!normalMode) {
5959             Slog.i(TAG, "Launching preboot mode app: " + app);
5960         }
5961
5962         if (localLOGV) Slog.v(
5963             TAG, "New app record " + app
5964             + " thread=" + thread.asBinder() + " pid=" + pid);
5965         try {
5966             int testMode = IApplicationThread.DEBUG_OFF;
5967             if (mDebugApp != null && mDebugApp.equals(processName)) {
5968                 testMode = mWaitForDebugger
5969                     ? IApplicationThread.DEBUG_WAIT
5970                     : IApplicationThread.DEBUG_ON;
5971                 app.debugging = true;
5972                 if (mDebugTransient) {
5973                     mDebugApp = mOrigDebugApp;
5974                     mWaitForDebugger = mOrigWaitForDebugger;
5975                 }
5976             }
5977             String profileFile = app.instrumentationProfileFile;
5978             ParcelFileDescriptor profileFd = null;
5979             int samplingInterval = 0;
5980             boolean profileAutoStop = false;
5981             if (mProfileApp != null && mProfileApp.equals(processName)) {
5982                 mProfileProc = app;
5983                 profileFile = mProfileFile;
5984                 profileFd = mProfileFd;
5985                 samplingInterval = mSamplingInterval;
5986                 profileAutoStop = mAutoStopProfiler;
5987             }
5988             boolean enableOpenGlTrace = false;
5989             if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5990                 enableOpenGlTrace = true;
5991                 mOpenGlTraceApp = null;
5992             }
5993
5994             // If the app is being launched for restore or full backup, set it up specially
5995             boolean isRestrictedBackupMode = false;
5996             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5997                 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5998                         || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5999                         || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6000             }
6001
6002             ensurePackageDexOpt(app.instrumentationInfo != null
6003                     ? app.instrumentationInfo.packageName
6004                     : app.info.packageName);
6005             if (app.instrumentationClass != null) {
6006                 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6007             }
6008             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6009                     + processName + " with config " + mConfiguration);
6010             ApplicationInfo appInfo = app.instrumentationInfo != null
6011                     ? app.instrumentationInfo : app.info;
6012             app.compat = compatibilityInfoForPackageLocked(appInfo);
6013             if (profileFd != null) {
6014                 profileFd = profileFd.dup();
6015             }
6016             ProfilerInfo profilerInfo = profileFile == null ? null
6017                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6018             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6019                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6020                     app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6021                     isRestrictedBackupMode || !normalMode, app.persistent,
6022                     new Configuration(mConfiguration), app.compat,
6023                     getCommonServicesLocked(app.isolated),
6024                     mCoreSettingsObserver.getCoreSettingsLocked());
6025             updateLruProcessLocked(app, false, null);
6026             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6027         } catch (Exception e) {
6028             // todo: Yikes!  What should we do?  For now we will try to
6029             // start another process, but that could easily get us in
6030             // an infinite loop of restarting processes...
6031             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6032
6033             app.resetPackageList(mProcessStats);
6034             app.unlinkDeathRecipient();
6035             startProcessLocked(app, "bind fail", processName);
6036             return false;
6037         }
6038
6039         // Remove this record from the list of starting applications.
6040         mPersistentStartingProcesses.remove(app);
6041         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6042                 "Attach application locked removing on hold: " + app);
6043         mProcessesOnHold.remove(app);
6044
6045         boolean badApp = false;
6046         boolean didSomething = false;
6047
6048         // See if the top visible activity is waiting to run in this process...
6049         if (normalMode) {
6050             try {
6051                 if (mStackSupervisor.attachApplicationLocked(app)) {
6052                     didSomething = true;
6053                 }
6054             } catch (Exception e) {
6055                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6056                 badApp = true;
6057             }
6058         }
6059
6060         // Find any services that should be running in this process...
6061         if (!badApp) {
6062             try {
6063                 didSomething |= mServices.attachApplicationLocked(app, processName);
6064             } catch (Exception e) {
6065                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6066                 badApp = true;
6067             }
6068         }
6069
6070         // Check if a next-broadcast receiver is in this process...
6071         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6072             try {
6073                 didSomething |= sendPendingBroadcastsLocked(app);
6074             } catch (Exception e) {
6075                 // If the app died trying to launch the receiver we declare it 'bad'
6076                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6077                 badApp = true;
6078             }
6079         }
6080
6081         // Check whether the next backup agent is in this process...
6082         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6083             if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6084             ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6085             try {
6086                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6087                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6088                         mBackupTarget.backupMode);
6089             } catch (Exception e) {
6090                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6091                 badApp = true;
6092             }
6093         }
6094
6095         if (badApp) {
6096             app.kill("error during init", true);
6097             handleAppDiedLocked(app, false, true);
6098             return false;
6099         }
6100
6101         if (!didSomething) {
6102             updateOomAdjLocked();
6103         }
6104
6105         return true;
6106     }
6107
6108     @Override
6109     public final void attachApplication(IApplicationThread thread) {
6110         synchronized (this) {
6111             int callingPid = Binder.getCallingPid();
6112             final long origId = Binder.clearCallingIdentity();
6113             attachApplicationLocked(thread, callingPid);
6114             Binder.restoreCallingIdentity(origId);
6115         }
6116     }
6117
6118     @Override
6119     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6120         final long origId = Binder.clearCallingIdentity();
6121         synchronized (this) {
6122             ActivityStack stack = ActivityRecord.getStackLocked(token);
6123             if (stack != null) {
6124                 ActivityRecord r =
6125                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6126                 if (stopProfiling) {
6127                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6128                         try {
6129                             mProfileFd.close();
6130                         } catch (IOException e) {
6131                         }
6132                         clearProfilerLocked();
6133                     }
6134                 }
6135             }
6136         }
6137         Binder.restoreCallingIdentity(origId);
6138     }
6139
6140     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6141         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6142                 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6143     }
6144
6145     void enableScreenAfterBoot() {
6146         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6147                 SystemClock.uptimeMillis());
6148         mWindowManager.enableScreenAfterBoot();
6149
6150         synchronized (this) {
6151             updateEventDispatchingLocked();
6152         }
6153     }
6154
6155     @Override
6156     public void showBootMessage(final CharSequence msg, final boolean always) {
6157         enforceNotIsolatedCaller("showBootMessage");
6158         mWindowManager.showBootMessage(msg, always);
6159     }
6160
6161     @Override
6162     public void keyguardWaitingForActivityDrawn() {
6163         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6164         final long token = Binder.clearCallingIdentity();
6165         try {
6166             synchronized (this) {
6167                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6168                 mWindowManager.keyguardWaitingForActivityDrawn();
6169                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6170                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6171                     updateSleepIfNeededLocked();
6172                 }
6173             }
6174         } finally {
6175             Binder.restoreCallingIdentity(token);
6176         }
6177     }
6178
6179     final void finishBooting() {
6180         synchronized (this) {
6181             if (!mBootAnimationComplete) {
6182                 mCallFinishBooting = true;
6183                 return;
6184             }
6185             mCallFinishBooting = false;
6186         }
6187
6188         ArraySet<String> completedIsas = new ArraySet<String>();
6189         for (String abi : Build.SUPPORTED_ABIS) {
6190             Process.establishZygoteConnectionForAbi(abi);
6191             final String instructionSet = VMRuntime.getInstructionSet(abi);
6192             if (!completedIsas.contains(instructionSet)) {
6193                 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6194                     Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6195                 }
6196                 completedIsas.add(instructionSet);
6197             }
6198         }
6199
6200         IntentFilter pkgFilter = new IntentFilter();
6201         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6202         pkgFilter.addDataScheme("package");
6203         mContext.registerReceiver(new BroadcastReceiver() {
6204             @Override
6205             public void onReceive(Context context, Intent intent) {
6206                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6207                 if (pkgs != null) {
6208                     for (String pkg : pkgs) {
6209                         synchronized (ActivityManagerService.this) {
6210                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6211                                     0, "finished booting")) {
6212                                 setResultCode(Activity.RESULT_OK);
6213                                 return;
6214                             }
6215                         }
6216                     }
6217                 }
6218             }
6219         }, pkgFilter);
6220
6221         // Let system services know.
6222         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6223
6224         synchronized (this) {
6225             // Ensure that any processes we had put on hold are now started
6226             // up.
6227             final int NP = mProcessesOnHold.size();
6228             if (NP > 0) {
6229                 ArrayList<ProcessRecord> procs =
6230                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6231                 for (int ip=0; ip<NP; ip++) {
6232                     if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6233                             + procs.get(ip));
6234                     startProcessLocked(procs.get(ip), "on-hold", null);
6235                 }
6236             }
6237
6238             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6239                 // Start looking for apps that are abusing wake locks.
6240                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6241                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6242                 // Tell anyone interested that we are done booting!
6243                 SystemProperties.set("sys.boot_completed", "1");
6244
6245                 // And trigger dev.bootcomplete if we are not showing encryption progress
6246                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6247                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6248                     SystemProperties.set("dev.bootcomplete", "1");
6249                 }
6250                 for (int i=0; i<mStartedUsers.size(); i++) {
6251                     UserStartedState uss = mStartedUsers.valueAt(i);
6252                     if (uss.mState == UserStartedState.STATE_BOOTING) {
6253                         uss.mState = UserStartedState.STATE_RUNNING;
6254                         final int userId = mStartedUsers.keyAt(i);
6255                         Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6256                         intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6257                         intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6258                         broadcastIntentLocked(null, null, intent, null,
6259                                 new IIntentReceiver.Stub() {
6260                                     @Override
6261                                     public void performReceive(Intent intent, int resultCode,
6262                                             String data, Bundle extras, boolean ordered,
6263                                             boolean sticky, int sendingUser) {
6264                                         synchronized (ActivityManagerService.this) {
6265                                             requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6266                                                     true, false);
6267                                         }
6268                                     }
6269                                 },
6270                                 0, null, null,
6271                                 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6272                                 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6273                                 userId);
6274                     }
6275                 }
6276                 scheduleStartProfilesLocked();
6277             }
6278         }
6279     }
6280
6281     @Override
6282     public void bootAnimationComplete() {
6283         final boolean callFinishBooting;
6284         synchronized (this) {
6285             callFinishBooting = mCallFinishBooting;
6286             mBootAnimationComplete = true;
6287         }
6288         if (callFinishBooting) {
6289             finishBooting();
6290         }
6291     }
6292
6293     @Override
6294     public void systemBackupRestored() {
6295         synchronized (this) {
6296             if (mSystemReady) {
6297                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
6298             } else {
6299                 Slog.w(TAG, "System backup restored before system is ready");
6300             }
6301         }
6302     }
6303
6304     final void ensureBootCompleted() {
6305         boolean booting;
6306         boolean enableScreen;
6307         synchronized (this) {
6308             booting = mBooting;
6309             mBooting = false;
6310             enableScreen = !mBooted;
6311             mBooted = true;
6312         }
6313
6314         if (booting) {
6315             finishBooting();
6316         }
6317
6318         if (enableScreen) {
6319             enableScreenAfterBoot();
6320         }
6321     }
6322
6323     @Override
6324     public final void activityResumed(IBinder token) {
6325         final long origId = Binder.clearCallingIdentity();
6326         synchronized(this) {
6327             ActivityStack stack = ActivityRecord.getStackLocked(token);
6328             if (stack != null) {
6329                 ActivityRecord.activityResumedLocked(token);
6330             }
6331         }
6332         Binder.restoreCallingIdentity(origId);
6333     }
6334
6335     @Override
6336     public final void activityPaused(IBinder token) {
6337         final long origId = Binder.clearCallingIdentity();
6338         synchronized(this) {
6339             ActivityStack stack = ActivityRecord.getStackLocked(token);
6340             if (stack != null) {
6341                 stack.activityPausedLocked(token, false);
6342             }
6343         }
6344         Binder.restoreCallingIdentity(origId);
6345     }
6346
6347     @Override
6348     public final void activityStopped(IBinder token, Bundle icicle,
6349             PersistableBundle persistentState, CharSequence description) {
6350         if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6351
6352         // Refuse possible leaked file descriptors
6353         if (icicle != null && icicle.hasFileDescriptors()) {
6354             throw new IllegalArgumentException("File descriptors passed in Bundle");
6355         }
6356
6357         final long origId = Binder.clearCallingIdentity();
6358
6359         synchronized (this) {
6360             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6361             if (r != null) {
6362                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6363             }
6364         }
6365
6366         trimApplications();
6367
6368         Binder.restoreCallingIdentity(origId);
6369     }
6370
6371     @Override
6372     public final void activityDestroyed(IBinder token) {
6373         if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6374         synchronized (this) {
6375             ActivityStack stack = ActivityRecord.getStackLocked(token);
6376             if (stack != null) {
6377                 stack.activityDestroyedLocked(token, "activityDestroyed");
6378             }
6379         }
6380     }
6381
6382     @Override
6383     public final void backgroundResourcesReleased(IBinder token) {
6384         final long origId = Binder.clearCallingIdentity();
6385         try {
6386             synchronized (this) {
6387                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6388                 if (stack != null) {
6389                     stack.backgroundResourcesReleased();
6390                 }
6391             }
6392         } finally {
6393             Binder.restoreCallingIdentity(origId);
6394         }
6395     }
6396
6397     @Override
6398     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6399         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6400     }
6401
6402     @Override
6403     public final void notifyEnterAnimationComplete(IBinder token) {
6404         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6405     }
6406
6407     @Override
6408     public String getCallingPackage(IBinder token) {
6409         synchronized (this) {
6410             ActivityRecord r = getCallingRecordLocked(token);
6411             return r != null ? r.info.packageName : null;
6412         }
6413     }
6414
6415     @Override
6416     public ComponentName getCallingActivity(IBinder token) {
6417         synchronized (this) {
6418             ActivityRecord r = getCallingRecordLocked(token);
6419             return r != null ? r.intent.getComponent() : null;
6420         }
6421     }
6422
6423     private ActivityRecord getCallingRecordLocked(IBinder token) {
6424         ActivityRecord r = ActivityRecord.isInStackLocked(token);
6425         if (r == null) {
6426             return null;
6427         }
6428         return r.resultTo;
6429     }
6430
6431     @Override
6432     public ComponentName getActivityClassForToken(IBinder token) {
6433         synchronized(this) {
6434             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6435             if (r == null) {
6436                 return null;
6437             }
6438             return r.intent.getComponent();
6439         }
6440     }
6441
6442     @Override
6443     public String getPackageForToken(IBinder token) {
6444         synchronized(this) {
6445             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6446             if (r == null) {
6447                 return null;
6448             }
6449             return r.packageName;
6450         }
6451     }
6452
6453     @Override
6454     public IIntentSender getIntentSender(int type,
6455             String packageName, IBinder token, String resultWho,
6456             int requestCode, Intent[] intents, String[] resolvedTypes,
6457             int flags, Bundle options, int userId) {
6458         enforceNotIsolatedCaller("getIntentSender");
6459         // Refuse possible leaked file descriptors
6460         if (intents != null) {
6461             if (intents.length < 1) {
6462                 throw new IllegalArgumentException("Intents array length must be >= 1");
6463             }
6464             for (int i=0; i<intents.length; i++) {
6465                 Intent intent = intents[i];
6466                 if (intent != null) {
6467                     if (intent.hasFileDescriptors()) {
6468                         throw new IllegalArgumentException("File descriptors passed in Intent");
6469                     }
6470                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6471                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6472                         throw new IllegalArgumentException(
6473                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6474                     }
6475                     intents[i] = new Intent(intent);
6476                 }
6477             }
6478             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6479                 throw new IllegalArgumentException(
6480                         "Intent array length does not match resolvedTypes length");
6481             }
6482         }
6483         if (options != null) {
6484             if (options.hasFileDescriptors()) {
6485                 throw new IllegalArgumentException("File descriptors passed in options");
6486             }
6487         }
6488
6489         synchronized(this) {
6490             int callingUid = Binder.getCallingUid();
6491             int origUserId = userId;
6492             userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6493                     type == ActivityManager.INTENT_SENDER_BROADCAST,
6494                     ALLOW_NON_FULL, "getIntentSender", null);
6495             if (origUserId == UserHandle.USER_CURRENT) {
6496                 // We don't want to evaluate this until the pending intent is
6497                 // actually executed.  However, we do want to always do the
6498                 // security checking for it above.
6499                 userId = UserHandle.USER_CURRENT;
6500             }
6501             try {
6502                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6503                     int uid = AppGlobals.getPackageManager()
6504                             .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6505                     if (!UserHandle.isSameApp(callingUid, uid)) {
6506                         String msg = "Permission Denial: getIntentSender() from pid="
6507                             + Binder.getCallingPid()
6508                             + ", uid=" + Binder.getCallingUid()
6509                             + ", (need uid=" + uid + ")"
6510                             + " is not allowed to send as package " + packageName;
6511                         Slog.w(TAG, msg);
6512                         throw new SecurityException(msg);
6513                     }
6514                 }
6515
6516                 return getIntentSenderLocked(type, packageName, callingUid, userId,
6517                         token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6518
6519             } catch (RemoteException e) {
6520                 throw new SecurityException(e);
6521             }
6522         }
6523     }
6524
6525     IIntentSender getIntentSenderLocked(int type, String packageName,
6526             int callingUid, int userId, IBinder token, String resultWho,
6527             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6528             Bundle options) {
6529         if (DEBUG_MU)
6530             Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6531         ActivityRecord activity = null;
6532         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6533             activity = ActivityRecord.isInStackLocked(token);
6534             if (activity == null) {
6535                 return null;
6536             }
6537             if (activity.finishing) {
6538                 return null;
6539             }
6540         }
6541
6542         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6543         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6544         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6545         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6546                 |PendingIntent.FLAG_UPDATE_CURRENT);
6547
6548         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6549                 type, packageName, activity, resultWho,
6550                 requestCode, intents, resolvedTypes, flags, options, userId);
6551         WeakReference<PendingIntentRecord> ref;
6552         ref = mIntentSenderRecords.get(key);
6553         PendingIntentRecord rec = ref != null ? ref.get() : null;
6554         if (rec != null) {
6555             if (!cancelCurrent) {
6556                 if (updateCurrent) {
6557                     if (rec.key.requestIntent != null) {
6558                         rec.key.requestIntent.replaceExtras(intents != null ?
6559                                 intents[intents.length - 1] : null);
6560                     }
6561                     if (intents != null) {
6562                         intents[intents.length-1] = rec.key.requestIntent;
6563                         rec.key.allIntents = intents;
6564                         rec.key.allResolvedTypes = resolvedTypes;
6565                     } else {
6566                         rec.key.allIntents = null;
6567                         rec.key.allResolvedTypes = null;
6568                     }
6569                 }
6570                 return rec;
6571             }
6572             rec.canceled = true;
6573             mIntentSenderRecords.remove(key);
6574         }
6575         if (noCreate) {
6576             return rec;
6577         }
6578         rec = new PendingIntentRecord(this, key, callingUid);
6579         mIntentSenderRecords.put(key, rec.ref);
6580         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6581             if (activity.pendingResults == null) {
6582                 activity.pendingResults
6583                         = new HashSet<WeakReference<PendingIntentRecord>>();
6584             }
6585             activity.pendingResults.add(rec.ref);
6586         }
6587         return rec;
6588     }
6589
6590     @Override
6591     public void cancelIntentSender(IIntentSender sender) {
6592         if (!(sender instanceof PendingIntentRecord)) {
6593             return;
6594         }
6595         synchronized(this) {
6596             PendingIntentRecord rec = (PendingIntentRecord)sender;
6597             try {
6598                 int uid = AppGlobals.getPackageManager()
6599                         .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6600                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6601                     String msg = "Permission Denial: cancelIntentSender() from pid="
6602                         + Binder.getCallingPid()
6603                         + ", uid=" + Binder.getCallingUid()
6604                         + " is not allowed to cancel packges "
6605                         + rec.key.packageName;
6606                     Slog.w(TAG, msg);
6607                     throw new SecurityException(msg);
6608                 }
6609             } catch (RemoteException e) {
6610                 throw new SecurityException(e);
6611             }
6612             cancelIntentSenderLocked(rec, true);
6613         }
6614     }
6615
6616     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6617         rec.canceled = true;
6618         mIntentSenderRecords.remove(rec.key);
6619         if (cleanActivity && rec.key.activity != null) {
6620             rec.key.activity.pendingResults.remove(rec.ref);
6621         }
6622     }
6623
6624     @Override
6625     public String getPackageForIntentSender(IIntentSender pendingResult) {
6626         if (!(pendingResult instanceof PendingIntentRecord)) {
6627             return null;
6628         }
6629         try {
6630             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631             return res.key.packageName;
6632         } catch (ClassCastException e) {
6633         }
6634         return null;
6635     }
6636
6637     @Override
6638     public int getUidForIntentSender(IIntentSender sender) {
6639         if (sender instanceof PendingIntentRecord) {
6640             try {
6641                 PendingIntentRecord res = (PendingIntentRecord)sender;
6642                 return res.uid;
6643             } catch (ClassCastException e) {
6644             }
6645         }
6646         return -1;
6647     }
6648
6649     @Override
6650     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6651         if (!(pendingResult instanceof PendingIntentRecord)) {
6652             return false;
6653         }
6654         try {
6655             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6656             if (res.key.allIntents == null) {
6657                 return false;
6658             }
6659             for (int i=0; i<res.key.allIntents.length; i++) {
6660                 Intent intent = res.key.allIntents[i];
6661                 if (intent.getPackage() != null && intent.getComponent() != null) {
6662                     return false;
6663                 }
6664             }
6665             return true;
6666         } catch (ClassCastException e) {
6667         }
6668         return false;
6669     }
6670
6671     @Override
6672     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6673         if (!(pendingResult instanceof PendingIntentRecord)) {
6674             return false;
6675         }
6676         try {
6677             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6678             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6679                 return true;
6680             }
6681             return false;
6682         } catch (ClassCastException e) {
6683         }
6684         return false;
6685     }
6686
6687     @Override
6688     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6689         if (!(pendingResult instanceof PendingIntentRecord)) {
6690             return null;
6691         }
6692         try {
6693             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6694             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6695         } catch (ClassCastException e) {
6696         }
6697         return null;
6698     }
6699
6700     @Override
6701     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6702         if (!(pendingResult instanceof PendingIntentRecord)) {
6703             return null;
6704         }
6705         try {
6706             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6707             Intent intent = res.key.requestIntent;
6708             if (intent != null) {
6709                 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6710                         || res.lastTagPrefix.equals(prefix))) {
6711                     return res.lastTag;
6712                 }
6713                 res.lastTagPrefix = prefix;
6714                 StringBuilder sb = new StringBuilder(128);
6715                 if (prefix != null) {
6716                     sb.append(prefix);
6717                 }
6718                 if (intent.getAction() != null) {
6719                     sb.append(intent.getAction());
6720                 } else if (intent.getComponent() != null) {
6721                     intent.getComponent().appendShortString(sb);
6722                 } else {
6723                     sb.append("?");
6724                 }
6725                 return res.lastTag = sb.toString();
6726             }
6727         } catch (ClassCastException e) {
6728         }
6729         return null;
6730     }
6731
6732     @Override
6733     public void setProcessLimit(int max) {
6734         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6735                 "setProcessLimit()");
6736         synchronized (this) {
6737             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6738             mProcessLimitOverride = max;
6739         }
6740         trimApplications();
6741     }
6742
6743     @Override
6744     public int getProcessLimit() {
6745         synchronized (this) {
6746             return mProcessLimitOverride;
6747         }
6748     }
6749
6750     void foregroundTokenDied(ForegroundToken token) {
6751         synchronized (ActivityManagerService.this) {
6752             synchronized (mPidsSelfLocked) {
6753                 ForegroundToken cur
6754                     = mForegroundProcesses.get(token.pid);
6755                 if (cur != token) {
6756                     return;
6757                 }
6758                 mForegroundProcesses.remove(token.pid);
6759                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6760                 if (pr == null) {
6761                     return;
6762                 }
6763                 pr.forcingToForeground = null;
6764                 updateProcessForegroundLocked(pr, false, false);
6765             }
6766             updateOomAdjLocked();
6767         }
6768     }
6769
6770     @Override
6771     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6772         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6773                 "setProcessForeground()");
6774         synchronized(this) {
6775             boolean changed = false;
6776             
6777             synchronized (mPidsSelfLocked) {
6778                 ProcessRecord pr = mPidsSelfLocked.get(pid);
6779                 if (pr == null && isForeground) {
6780                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6781                     return;
6782                 }
6783                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6784                 if (oldToken != null) {
6785                     oldToken.token.unlinkToDeath(oldToken, 0);
6786                     mForegroundProcesses.remove(pid);
6787                     if (pr != null) {
6788                         pr.forcingToForeground = null;
6789                     }
6790                     changed = true;
6791                 }
6792                 if (isForeground && token != null) {
6793                     ForegroundToken newToken = new ForegroundToken() {
6794                         @Override
6795                         public void binderDied() {
6796                             foregroundTokenDied(this);
6797                         }
6798                     };
6799                     newToken.pid = pid;
6800                     newToken.token = token;
6801                     try {
6802                         token.linkToDeath(newToken, 0);
6803                         mForegroundProcesses.put(pid, newToken);
6804                         pr.forcingToForeground = token;
6805                         changed = true;
6806                     } catch (RemoteException e) {
6807                         // If the process died while doing this, we will later
6808                         // do the cleanup with the process death link.
6809                     }
6810                 }
6811             }
6812             
6813             if (changed) {
6814                 updateOomAdjLocked();
6815             }
6816         }
6817     }
6818     
6819     // =========================================================
6820     // PERMISSIONS
6821     // =========================================================
6822
6823     static class PermissionController extends IPermissionController.Stub {
6824         ActivityManagerService mActivityManagerService;
6825         PermissionController(ActivityManagerService activityManagerService) {
6826             mActivityManagerService = activityManagerService;
6827         }
6828
6829         @Override
6830         public boolean checkPermission(String permission, int pid, int uid) {
6831             return mActivityManagerService.checkPermission(permission, pid,
6832                     uid) == PackageManager.PERMISSION_GRANTED;
6833         }
6834     }
6835
6836     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6837         @Override
6838         public int checkComponentPermission(String permission, int pid, int uid,
6839                 int owningUid, boolean exported) {
6840             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6841                     owningUid, exported);
6842         }
6843
6844         @Override
6845         public Object getAMSLock() {
6846             return ActivityManagerService.this;
6847         }
6848     }
6849
6850     /**
6851      * This can be called with or without the global lock held.
6852      */
6853     int checkComponentPermission(String permission, int pid, int uid,
6854             int owningUid, boolean exported) {
6855         if (pid == MY_PID) {
6856             return PackageManager.PERMISSION_GRANTED;
6857         }
6858         return ActivityManager.checkComponentPermission(permission, uid,
6859                 owningUid, exported);
6860     }
6861
6862     /**
6863      * As the only public entry point for permissions checking, this method
6864      * can enforce the semantic that requesting a check on a null global
6865      * permission is automatically denied.  (Internally a null permission
6866      * string is used when calling {@link #checkComponentPermission} in cases
6867      * when only uid-based security is needed.)
6868      * 
6869      * This can be called with or without the global lock held.
6870      */
6871     @Override
6872     public int checkPermission(String permission, int pid, int uid) {
6873         if (permission == null) {
6874             return PackageManager.PERMISSION_DENIED;
6875         }
6876         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6877     }
6878
6879     @Override
6880     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6881         if (permission == null) {
6882             return PackageManager.PERMISSION_DENIED;
6883         }
6884
6885         // We might be performing an operation on behalf of an indirect binder
6886         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6887         // client identity accordingly before proceeding.
6888         Identity tlsIdentity = sCallerIdentity.get();
6889         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6890             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6891                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6892             uid = tlsIdentity.uid;
6893             pid = tlsIdentity.pid;
6894         }
6895
6896         return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6897     }
6898
6899     /**
6900      * Binder IPC calls go through the public entry point.
6901      * This can be called with or without the global lock held.
6902      */
6903     int checkCallingPermission(String permission) {
6904         return checkPermission(permission,
6905                 Binder.getCallingPid(),
6906                 UserHandle.getAppId(Binder.getCallingUid()));
6907     }
6908
6909     /**
6910      * This can be called with or without the global lock held.
6911      */
6912     void enforceCallingPermission(String permission, String func) {
6913         if (checkCallingPermission(permission)
6914                 == PackageManager.PERMISSION_GRANTED) {
6915             return;
6916         }
6917
6918         String msg = "Permission Denial: " + func + " from pid="
6919                 + Binder.getCallingPid()
6920                 + ", uid=" + Binder.getCallingUid()
6921                 + " requires " + permission;
6922         Slog.w(TAG, msg);
6923         throw new SecurityException(msg);
6924     }
6925
6926     /**
6927      * Determine if UID is holding permissions required to access {@link Uri} in
6928      * the given {@link ProviderInfo}. Final permission checking is always done
6929      * in {@link ContentProvider}.
6930      */
6931     private final boolean checkHoldingPermissionsLocked(
6932             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6933         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6934                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6935         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6936             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6937                     != PERMISSION_GRANTED) {
6938                 return false;
6939             }
6940         }
6941         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6942     }
6943
6944     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6945             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6946         if (pi.applicationInfo.uid == uid) {
6947             return true;
6948         } else if (!pi.exported) {
6949             return false;
6950         }
6951
6952         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6953         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6954         try {
6955             // check if target holds top-level <provider> permissions
6956             if (!readMet && pi.readPermission != null && considerUidPermissions
6957                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6958                 readMet = true;
6959             }
6960             if (!writeMet && pi.writePermission != null && considerUidPermissions
6961                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6962                 writeMet = true;
6963             }
6964
6965             // track if unprotected read/write is allowed; any denied
6966             // <path-permission> below removes this ability
6967             boolean allowDefaultRead = pi.readPermission == null;
6968             boolean allowDefaultWrite = pi.writePermission == null;
6969
6970             // check if target holds any <path-permission> that match uri
6971             final PathPermission[] pps = pi.pathPermissions;
6972             if (pps != null) {
6973                 final String path = grantUri.uri.getPath();
6974                 int i = pps.length;
6975                 while (i > 0 && (!readMet || !writeMet)) {
6976                     i--;
6977                     PathPermission pp = pps[i];
6978                     if (pp.match(path)) {
6979                         if (!readMet) {
6980                             final String pprperm = pp.getReadPermission();
6981                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6982                                     + pprperm + " for " + pp.getPath()
6983                                     + ": match=" + pp.match(path)
6984                                     + " check=" + pm.checkUidPermission(pprperm, uid));
6985                             if (pprperm != null) {
6986                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6987                                         == PERMISSION_GRANTED) {
6988                                     readMet = true;
6989                                 } else {
6990                                     allowDefaultRead = false;
6991                                 }
6992                             }
6993                         }
6994                         if (!writeMet) {
6995                             final String ppwperm = pp.getWritePermission();
6996                             if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6997                                     + ppwperm + " for " + pp.getPath()
6998                                     + ": match=" + pp.match(path)
6999                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7000                             if (ppwperm != null) {
7001                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7002                                         == PERMISSION_GRANTED) {
7003                                     writeMet = true;
7004                                 } else {
7005                                     allowDefaultWrite = false;
7006                                 }
7007                             }
7008                         }
7009                     }
7010                 }
7011             }
7012
7013             // grant unprotected <provider> read/write, if not blocked by
7014             // <path-permission> above
7015             if (allowDefaultRead) readMet = true;
7016             if (allowDefaultWrite) writeMet = true;
7017
7018         } catch (RemoteException e) {
7019             return false;
7020         }
7021
7022         return readMet && writeMet;
7023     }
7024
7025     private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7026         ProviderInfo pi = null;
7027         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7028         if (cpr != null) {
7029             pi = cpr.info;
7030         } else {
7031             try {
7032                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7033                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7034             } catch (RemoteException ex) {
7035             }
7036         }
7037         return pi;
7038     }
7039
7040     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7041         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7042         if (targetUris != null) {
7043             return targetUris.get(grantUri);
7044         }
7045         return null;
7046     }
7047
7048     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7049             String targetPkg, int targetUid, GrantUri grantUri) {
7050         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7051         if (targetUris == null) {
7052             targetUris = Maps.newArrayMap();
7053             mGrantedUriPermissions.put(targetUid, targetUris);
7054         }
7055
7056         UriPermission perm = targetUris.get(grantUri);
7057         if (perm == null) {
7058             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7059             targetUris.put(grantUri, perm);
7060         }
7061
7062         return perm;
7063     }
7064
7065     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7066             final int modeFlags) {
7067         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7068         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7069                 : UriPermission.STRENGTH_OWNED;
7070
7071         // Root gets to do everything.
7072         if (uid == 0) {
7073             return true;
7074         }
7075
7076         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7077         if (perms == null) return false;
7078
7079         // First look for exact match
7080         final UriPermission exactPerm = perms.get(grantUri);
7081         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7082             return true;
7083         }
7084
7085         // No exact match, look for prefixes
7086         final int N = perms.size();
7087         for (int i = 0; i < N; i++) {
7088             final UriPermission perm = perms.valueAt(i);
7089             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7090                     && perm.getStrength(modeFlags) >= minStrength) {
7091                 return true;
7092             }
7093         }
7094
7095         return false;
7096     }
7097
7098     /**
7099      * @param uri This uri must NOT contain an embedded userId.
7100      * @param userId The userId in which the uri is to be resolved.
7101      */
7102     @Override
7103     public int checkUriPermission(Uri uri, int pid, int uid,
7104             final int modeFlags, int userId, IBinder callerToken) {
7105         enforceNotIsolatedCaller("checkUriPermission");
7106
7107         // Another redirected-binder-call permissions check as in
7108         // {@link checkPermissionWithToken}.
7109         Identity tlsIdentity = sCallerIdentity.get();
7110         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7111             uid = tlsIdentity.uid;
7112             pid = tlsIdentity.pid;
7113         }
7114
7115         // Our own process gets to do everything.
7116         if (pid == MY_PID) {
7117             return PackageManager.PERMISSION_GRANTED;
7118         }
7119         synchronized (this) {
7120             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7121                     ? PackageManager.PERMISSION_GRANTED
7122                     : PackageManager.PERMISSION_DENIED;
7123         }
7124     }
7125
7126     /**
7127      * Check if the targetPkg can be granted permission to access uri by
7128      * the callingUid using the given modeFlags.  Throws a security exception
7129      * if callingUid is not allowed to do this.  Returns the uid of the target
7130      * if the URI permission grant should be performed; returns -1 if it is not
7131      * needed (for example targetPkg already has permission to access the URI).
7132      * If you already know the uid of the target, you can supply it in
7133      * lastTargetUid else set that to -1.
7134      */
7135     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7136             final int modeFlags, int lastTargetUid) {
7137         if (!Intent.isAccessUriMode(modeFlags)) {
7138             return -1;
7139         }
7140
7141         if (targetPkg != null) {
7142             if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7143                     "Checking grant " + targetPkg + " permission to " + grantUri);
7144         }
7145         
7146         final IPackageManager pm = AppGlobals.getPackageManager();
7147
7148         // If this is not a content: uri, we can't do anything with it.
7149         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7150             if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7151                     "Can't grant URI permission for non-content URI: " + grantUri);
7152             return -1;
7153         }
7154
7155         final String authority = grantUri.uri.getAuthority();
7156         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7157         if (pi == null) {
7158             Slog.w(TAG, "No content provider found for permission check: " +
7159                     grantUri.uri.toSafeString());
7160             return -1;
7161         }
7162
7163         int targetUid = lastTargetUid;
7164         if (targetUid < 0 && targetPkg != null) {
7165             try {
7166                 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7167                 if (targetUid < 0) {
7168                     if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7169                             "Can't grant URI permission no uid for: " + targetPkg);
7170                     return -1;
7171                 }
7172             } catch (RemoteException ex) {
7173                 return -1;
7174             }
7175         }
7176
7177         if (targetUid >= 0) {
7178             // First...  does the target actually need this permission?
7179             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7180                 // No need to grant the target this permission.
7181                 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7182                         "Target " + targetPkg + " already has full permission to " + grantUri);
7183                 return -1;
7184             }
7185         } else {
7186             // First...  there is no target package, so can anyone access it?
7187             boolean allowed = pi.exported;
7188             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7189                 if (pi.readPermission != null) {
7190                     allowed = false;
7191                 }
7192             }
7193             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7194                 if (pi.writePermission != null) {
7195                     allowed = false;
7196                 }
7197             }
7198             if (allowed) {
7199                 return -1;
7200             }
7201         }
7202
7203         /* There is a special cross user grant if:
7204          * - The target is on another user.
7205          * - Apps on the current user can access the uri without any uid permissions.
7206          * In this case, we grant a uri permission, even if the ContentProvider does not normally
7207          * grant uri permissions.
7208          */
7209         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7210                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7211                 modeFlags, false /*without considering the uid permissions*/);
7212
7213         // Second...  is the provider allowing granting of URI permissions?
7214         if (!specialCrossUserGrant) {
7215             if (!pi.grantUriPermissions) {
7216                 throw new SecurityException("Provider " + pi.packageName
7217                         + "/" + pi.name
7218                         + " does not allow granting of Uri permissions (uri "
7219                         + grantUri + ")");
7220             }
7221             if (pi.uriPermissionPatterns != null) {
7222                 final int N = pi.uriPermissionPatterns.length;
7223                 boolean allowed = false;
7224                 for (int i=0; i<N; i++) {
7225                     if (pi.uriPermissionPatterns[i] != null
7226                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7227                         allowed = true;
7228                         break;
7229                     }
7230                 }
7231                 if (!allowed) {
7232                     throw new SecurityException("Provider " + pi.packageName
7233                             + "/" + pi.name
7234                             + " does not allow granting of permission to path of Uri "
7235                             + grantUri);
7236                 }
7237             }
7238         }
7239
7240         // Third...  does the caller itself have permission to access
7241         // this uri?
7242         final int callingAppId = UserHandle.getAppId(callingUid);
7243         if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
7244             Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
7245                     + " grant to " + grantUri + "; use startActivityAsCaller() instead");
7246             return -1;
7247         } else {
7248             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7249                 // Require they hold a strong enough Uri permission
7250                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7251                     throw new SecurityException("Uid " + callingUid
7252                             + " does not have permission to uri " + grantUri);
7253                 }
7254             }
7255         }
7256         return targetUid;
7257     }
7258
7259     /**
7260      * @param uri This uri must NOT contain an embedded userId.
7261      * @param userId The userId in which the uri is to be resolved.
7262      */
7263     @Override
7264     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7265             final int modeFlags, int userId) {
7266         enforceNotIsolatedCaller("checkGrantUriPermission");
7267         synchronized(this) {
7268             return checkGrantUriPermissionLocked(callingUid, targetPkg,
7269                     new GrantUri(userId, uri, false), modeFlags, -1);
7270         }
7271     }
7272
7273     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7274             final int modeFlags, UriPermissionOwner owner) {
7275         if (!Intent.isAccessUriMode(modeFlags)) {
7276             return;
7277         }
7278
7279         // So here we are: the caller has the assumed permission
7280         // to the uri, and the target doesn't.  Let's now give this to
7281         // the target.
7282
7283         if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7284                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7285
7286         final String authority = grantUri.uri.getAuthority();
7287         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7288         if (pi == null) {
7289             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7290             return;
7291         }
7292
7293         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7294             grantUri.prefix = true;
7295         }
7296         final UriPermission perm = findOrCreateUriPermissionLocked(
7297                 pi.packageName, targetPkg, targetUid, grantUri);
7298         perm.grantModes(modeFlags, owner);
7299     }
7300
7301     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7302             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7303         if (targetPkg == null) {
7304             throw new NullPointerException("targetPkg");
7305         }
7306         int targetUid;
7307         final IPackageManager pm = AppGlobals.getPackageManager();
7308         try {
7309             targetUid = pm.getPackageUid(targetPkg, targetUserId);
7310         } catch (RemoteException ex) {
7311             return;
7312         }
7313
7314         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7315                 targetUid);
7316         if (targetUid < 0) {
7317             return;
7318         }
7319
7320         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7321                 owner);
7322     }
7323
7324     static class NeededUriGrants extends ArrayList<GrantUri> {
7325         final String targetPkg;
7326         final int targetUid;
7327         final int flags;
7328
7329         NeededUriGrants(String targetPkg, int targetUid, int flags) {
7330             this.targetPkg = targetPkg;
7331             this.targetUid = targetUid;
7332             this.flags = flags;
7333         }
7334     }
7335
7336     /**
7337      * Like checkGrantUriPermissionLocked, but takes an Intent.
7338      */
7339     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7340             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7341         if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7342                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7343                 + " clip=" + (intent != null ? intent.getClipData() : null)
7344                 + " from " + intent + "; flags=0x"
7345                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7346
7347         if (targetPkg == null) {
7348             throw new NullPointerException("targetPkg");
7349         }
7350
7351         if (intent == null) {
7352             return null;
7353         }
7354         Uri data = intent.getData();
7355         ClipData clip = intent.getClipData();
7356         if (data == null && clip == null) {
7357             return null;
7358         }
7359         // Default userId for uris in the intent (if they don't specify it themselves)
7360         int contentUserHint = intent.getContentUserHint();
7361         if (contentUserHint == UserHandle.USER_CURRENT) {
7362             contentUserHint = UserHandle.getUserId(callingUid);
7363         }
7364         final IPackageManager pm = AppGlobals.getPackageManager();
7365         int targetUid;
7366         if (needed != null) {
7367             targetUid = needed.targetUid;
7368         } else {
7369             try {
7370                 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7371             } catch (RemoteException ex) {
7372                 return null;
7373             }
7374             if (targetUid < 0) {
7375                 if (DEBUG_URI_PERMISSION) {
7376                     Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7377                             + " on user " + targetUserId);
7378                 }
7379                 return null;
7380             }
7381         }
7382         if (data != null) {
7383             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7384             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7385                     targetUid);
7386             if (targetUid > 0) {
7387                 if (needed == null) {
7388                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
7389                 }
7390                 needed.add(grantUri);
7391             }
7392         }
7393         if (clip != null) {
7394             for (int i=0; i<clip.getItemCount(); i++) {
7395                 Uri uri = clip.getItemAt(i).getUri();
7396                 if (uri != null) {
7397                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7398                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7399                             targetUid);
7400                     if (targetUid > 0) {
7401                         if (needed == null) {
7402                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
7403                         }
7404                         needed.add(grantUri);
7405                     }
7406                 } else {
7407                     Intent clipIntent = clip.getItemAt(i).getIntent();
7408                     if (clipIntent != null) {
7409                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7410                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7411                         if (newNeeded != null) {
7412                             needed = newNeeded;
7413                         }
7414                     }
7415                 }
7416             }
7417         }
7418
7419         return needed;
7420     }
7421
7422     /**
7423      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7424      */
7425     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7426             UriPermissionOwner owner) {
7427         if (needed != null) {
7428             for (int i=0; i<needed.size(); i++) {
7429                 GrantUri grantUri = needed.get(i);
7430                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7431                         grantUri, needed.flags, owner);
7432             }
7433         }
7434     }
7435
7436     void grantUriPermissionFromIntentLocked(int callingUid,
7437             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7438         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7439                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7440         if (needed == null) {
7441             return;
7442         }
7443
7444         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7445     }
7446
7447     /**
7448      * @param uri This uri must NOT contain an embedded userId.
7449      * @param userId The userId in which the uri is to be resolved.
7450      */
7451     @Override
7452     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7453             final int modeFlags, int userId) {
7454         enforceNotIsolatedCaller("grantUriPermission");
7455         GrantUri grantUri = new GrantUri(userId, uri, false);
7456         synchronized(this) {
7457             final ProcessRecord r = getRecordForAppLocked(caller);
7458             if (r == null) {
7459                 throw new SecurityException("Unable to find app for caller "
7460                         + caller
7461                         + " when granting permission to uri " + grantUri);
7462             }
7463             if (targetPkg == null) {
7464                 throw new IllegalArgumentException("null target");
7465             }
7466             if (grantUri == null) {
7467                 throw new IllegalArgumentException("null uri");
7468             }
7469
7470             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7471                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7472                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7473                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7474
7475             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7476                     UserHandle.getUserId(r.uid));
7477         }
7478     }
7479
7480     void removeUriPermissionIfNeededLocked(UriPermission perm) {
7481         if (perm.modeFlags == 0) {
7482             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7483                     perm.targetUid);
7484             if (perms != null) {
7485                 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 
7486                         "Removing " + perm.targetUid + " permission to " + perm.uri);
7487
7488                 perms.remove(perm.uri);
7489                 if (perms.isEmpty()) {
7490                     mGrantedUriPermissions.remove(perm.targetUid);
7491                 }
7492             }
7493         }
7494     }
7495
7496     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7497         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7498
7499         final IPackageManager pm = AppGlobals.getPackageManager();
7500         final String authority = grantUri.uri.getAuthority();
7501         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7502         if (pi == null) {
7503             Slog.w(TAG, "No content provider found for permission revoke: "
7504                     + grantUri.toSafeString());
7505             return;
7506         }
7507
7508         // Does the caller have this permission on the URI?
7509         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7510             // If they don't have direct access to the URI, then revoke any
7511             // ownerless URI permissions that have been granted to them.
7512             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7513             if (perms != null) {
7514                 boolean persistChanged = false;
7515                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7516                     final UriPermission perm = it.next();
7517                     if (perm.uri.sourceUserId == grantUri.sourceUserId
7518                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7519                         if (DEBUG_URI_PERMISSION)
7520                             Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7521                                     " permission to " + perm.uri);
7522                         persistChanged |= perm.revokeModes(
7523                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7524                         if (perm.modeFlags == 0) {
7525                             it.remove();
7526                         }
7527                     }
7528                 }
7529                 if (perms.isEmpty()) {
7530                     mGrantedUriPermissions.remove(callingUid);
7531                 }
7532                 if (persistChanged) {
7533                     schedulePersistUriGrants();
7534                 }
7535             }
7536             return;
7537         }
7538
7539         boolean persistChanged = false;
7540
7541         // Go through all of the permissions and remove any that match.
7542         int N = mGrantedUriPermissions.size();
7543         for (int i = 0; i < N; i++) {
7544             final int targetUid = mGrantedUriPermissions.keyAt(i);
7545             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7546
7547             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7548                 final UriPermission perm = it.next();
7549                 if (perm.uri.sourceUserId == grantUri.sourceUserId
7550                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7551                     if (DEBUG_URI_PERMISSION)
7552                         Slog.v(TAG,
7553                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7554                     persistChanged |= perm.revokeModes(
7555                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7556                     if (perm.modeFlags == 0) {
7557                         it.remove();
7558                     }
7559                 }
7560             }
7561
7562             if (perms.isEmpty()) {
7563                 mGrantedUriPermissions.remove(targetUid);
7564                 N--;
7565                 i--;
7566             }
7567         }
7568
7569         if (persistChanged) {
7570             schedulePersistUriGrants();
7571         }
7572     }
7573
7574     /**
7575      * @param uri This uri must NOT contain an embedded userId.
7576      * @param userId The userId in which the uri is to be resolved.
7577      */
7578     @Override
7579     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7580             int userId) {
7581         enforceNotIsolatedCaller("revokeUriPermission");
7582         synchronized(this) {
7583             final ProcessRecord r = getRecordForAppLocked(caller);
7584             if (r == null) {
7585                 throw new SecurityException("Unable to find app for caller "
7586                         + caller
7587                         + " when revoking permission to uri " + uri);
7588             }
7589             if (uri == null) {
7590                 Slog.w(TAG, "revokeUriPermission: null uri");
7591                 return;
7592             }
7593
7594             if (!Intent.isAccessUriMode(modeFlags)) {
7595                 return;
7596             }
7597
7598             final IPackageManager pm = AppGlobals.getPackageManager();
7599             final String authority = uri.getAuthority();
7600             final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7601             if (pi == null) {
7602                 Slog.w(TAG, "No content provider found for permission revoke: "
7603                         + uri.toSafeString());
7604                 return;
7605             }
7606
7607             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7608         }
7609     }
7610
7611     /**
7612      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7613      * given package.
7614      *
7615      * @param packageName Package name to match, or {@code null} to apply to all
7616      *            packages.
7617      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7618      *            to all users.
7619      * @param persistable If persistable grants should be removed.
7620      */
7621     private void removeUriPermissionsForPackageLocked(
7622             String packageName, int userHandle, boolean persistable) {
7623         if (userHandle == UserHandle.USER_ALL && packageName == null) {
7624             throw new IllegalArgumentException("Must narrow by either package or user");
7625         }
7626
7627         boolean persistChanged = false;
7628
7629         int N = mGrantedUriPermissions.size();
7630         for (int i = 0; i < N; i++) {
7631             final int targetUid = mGrantedUriPermissions.keyAt(i);
7632             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7633
7634             // Only inspect grants matching user
7635             if (userHandle == UserHandle.USER_ALL
7636                     || userHandle == UserHandle.getUserId(targetUid)) {
7637                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7638                     final UriPermission perm = it.next();
7639
7640                     // Only inspect grants matching package
7641                     if (packageName == null || perm.sourcePkg.equals(packageName)
7642                             || perm.targetPkg.equals(packageName)) {
7643                         // Hacky solution as part of fixing a security bug; ignore
7644                         // grants associated with DownloadManager so we don't have
7645                         // to immediately launch it to regrant the permissions
7646                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
7647                                 && !persistable) continue;
7648
7649                         persistChanged |= perm.revokeModes(persistable
7650                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7651
7652                         // Only remove when no modes remain; any persisted grants
7653                         // will keep this alive.
7654                         if (perm.modeFlags == 0) {
7655                             it.remove();
7656                         }
7657                     }
7658                 }
7659
7660                 if (perms.isEmpty()) {
7661                     mGrantedUriPermissions.remove(targetUid);
7662                     N--;
7663                     i--;
7664                 }
7665             }
7666         }
7667
7668         if (persistChanged) {
7669             schedulePersistUriGrants();
7670         }
7671     }
7672
7673     @Override
7674     public IBinder newUriPermissionOwner(String name) {
7675         enforceNotIsolatedCaller("newUriPermissionOwner");
7676         synchronized(this) {
7677             UriPermissionOwner owner = new UriPermissionOwner(this, name);
7678             return owner.getExternalTokenLocked();
7679         }
7680     }
7681
7682     /**
7683      * @param uri This uri must NOT contain an embedded userId.
7684      * @param sourceUserId The userId in which the uri is to be resolved.
7685      * @param targetUserId The userId of the app that receives the grant.
7686      */
7687     @Override
7688     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7689             final int modeFlags, int sourceUserId, int targetUserId) {
7690         targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7691                 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7692         synchronized(this) {
7693             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7694             if (owner == null) {
7695                 throw new IllegalArgumentException("Unknown owner: " + token);
7696             }
7697             if (fromUid != Binder.getCallingUid()) {
7698                 if (Binder.getCallingUid() != Process.myUid()) {
7699                     // Only system code can grant URI permissions on behalf
7700                     // of other users.
7701                     throw new SecurityException("nice try");
7702                 }
7703             }
7704             if (targetPkg == null) {
7705                 throw new IllegalArgumentException("null target");
7706             }
7707             if (uri == null) {
7708                 throw new IllegalArgumentException("null uri");
7709             }
7710
7711             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7712                     modeFlags, owner, targetUserId);
7713         }
7714     }
7715
7716     /**
7717      * @param uri This uri must NOT contain an embedded userId.
7718      * @param userId The userId in which the uri is to be resolved.
7719      */
7720     @Override
7721     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7722         synchronized(this) {
7723             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7724             if (owner == null) {
7725                 throw new IllegalArgumentException("Unknown owner: " + token);
7726             }
7727
7728             if (uri == null) {
7729                 owner.removeUriPermissionsLocked(mode);
7730             } else {
7731                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7732             }
7733         }
7734     }
7735
7736     private void schedulePersistUriGrants() {
7737         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7738             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7739                     10 * DateUtils.SECOND_IN_MILLIS);
7740         }
7741     }
7742
7743     private void writeGrantedUriPermissions() {
7744         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7745
7746         // Snapshot permissions so we can persist without lock
7747         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7748         synchronized (this) {
7749             final int size = mGrantedUriPermissions.size();
7750             for (int i = 0; i < size; i++) {
7751                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7752                 for (UriPermission perm : perms.values()) {
7753                     if (perm.persistedModeFlags != 0) {
7754                         persist.add(perm.snapshot());
7755                     }
7756                 }
7757             }
7758         }
7759
7760         FileOutputStream fos = null;
7761         try {
7762             fos = mGrantFile.startWrite();
7763
7764             XmlSerializer out = new FastXmlSerializer();
7765             out.setOutput(fos, "utf-8");
7766             out.startDocument(null, true);
7767             out.startTag(null, TAG_URI_GRANTS);
7768             for (UriPermission.Snapshot perm : persist) {
7769                 out.startTag(null, TAG_URI_GRANT);
7770                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7771                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7772                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7773                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7774                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7775                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7776                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7777                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7778                 out.endTag(null, TAG_URI_GRANT);
7779             }
7780             out.endTag(null, TAG_URI_GRANTS);
7781             out.endDocument();
7782
7783             mGrantFile.finishWrite(fos);
7784         } catch (IOException e) {
7785             if (fos != null) {
7786                 mGrantFile.failWrite(fos);
7787             }
7788         }
7789     }
7790
7791     private void readGrantedUriPermissionsLocked() {
7792         if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7793
7794         final long now = System.currentTimeMillis();
7795
7796         FileInputStream fis = null;
7797         try {
7798             fis = mGrantFile.openRead();
7799             final XmlPullParser in = Xml.newPullParser();
7800             in.setInput(fis, null);
7801
7802             int type;
7803             while ((type = in.next()) != END_DOCUMENT) {
7804                 final String tag = in.getName();
7805                 if (type == START_TAG) {
7806                     if (TAG_URI_GRANT.equals(tag)) {
7807                         final int sourceUserId;
7808                         final int targetUserId;
7809                         final int userHandle = readIntAttribute(in,
7810                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7811                         if (userHandle != UserHandle.USER_NULL) {
7812                             // For backwards compatibility.
7813                             sourceUserId = userHandle;
7814                             targetUserId = userHandle;
7815                         } else {
7816                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7817                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7818                         }
7819                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7820                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7821                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7822                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7823                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7824                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7825
7826                         // Sanity check that provider still belongs to source package
7827                         final ProviderInfo pi = getProviderInfoLocked(
7828                                 uri.getAuthority(), sourceUserId);
7829                         if (pi != null && sourcePkg.equals(pi.packageName)) {
7830                             int targetUid = -1;
7831                             try {
7832                                 targetUid = AppGlobals.getPackageManager()
7833                                         .getPackageUid(targetPkg, targetUserId);
7834                             } catch (RemoteException e) {
7835                             }
7836                             if (targetUid != -1) {
7837                                 final UriPermission perm = findOrCreateUriPermissionLocked(
7838                                         sourcePkg, targetPkg, targetUid,
7839                                         new GrantUri(sourceUserId, uri, prefix));
7840                                 perm.initPersistedModes(modeFlags, createdTime);
7841                             }
7842                         } else {
7843                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7844                                     + " but instead found " + pi);
7845                         }
7846                     }
7847                 }
7848             }
7849         } catch (FileNotFoundException e) {
7850             // Missing grants is okay
7851         } catch (IOException e) {
7852             Slog.wtf(TAG, "Failed reading Uri grants", e);
7853         } catch (XmlPullParserException e) {
7854             Slog.wtf(TAG, "Failed reading Uri grants", e);
7855         } finally {
7856             IoUtils.closeQuietly(fis);
7857         }
7858     }
7859
7860     /**
7861      * @param uri This uri must NOT contain an embedded userId.
7862      * @param userId The userId in which the uri is to be resolved.
7863      */
7864     @Override
7865     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7866         enforceNotIsolatedCaller("takePersistableUriPermission");
7867
7868         Preconditions.checkFlagsArgument(modeFlags,
7869                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7870
7871         synchronized (this) {
7872             final int callingUid = Binder.getCallingUid();
7873             boolean persistChanged = false;
7874             GrantUri grantUri = new GrantUri(userId, uri, false);
7875
7876             UriPermission exactPerm = findUriPermissionLocked(callingUid,
7877                     new GrantUri(userId, uri, false));
7878             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7879                     new GrantUri(userId, uri, true));
7880
7881             final boolean exactValid = (exactPerm != null)
7882                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7883             final boolean prefixValid = (prefixPerm != null)
7884                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7885
7886             if (!(exactValid || prefixValid)) {
7887                 throw new SecurityException("No persistable permission grants found for UID "
7888                         + callingUid + " and Uri " + grantUri.toSafeString());
7889             }
7890
7891             if (exactValid) {
7892                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7893             }
7894             if (prefixValid) {
7895                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7896             }
7897
7898             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7899
7900             if (persistChanged) {
7901                 schedulePersistUriGrants();
7902             }
7903         }
7904     }
7905
7906     /**
7907      * @param uri This uri must NOT contain an embedded userId.
7908      * @param userId The userId in which the uri is to be resolved.
7909      */
7910     @Override
7911     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7912         enforceNotIsolatedCaller("releasePersistableUriPermission");
7913
7914         Preconditions.checkFlagsArgument(modeFlags,
7915                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7916
7917         synchronized (this) {
7918             final int callingUid = Binder.getCallingUid();
7919             boolean persistChanged = false;
7920
7921             UriPermission exactPerm = findUriPermissionLocked(callingUid,
7922                     new GrantUri(userId, uri, false));
7923             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7924                     new GrantUri(userId, uri, true));
7925             if (exactPerm == null && prefixPerm == null) {
7926                 throw new SecurityException("No permission grants found for UID " + callingUid
7927                         + " and Uri " + uri.toSafeString());
7928             }
7929
7930             if (exactPerm != null) {
7931                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7932                 removeUriPermissionIfNeededLocked(exactPerm);
7933             }
7934             if (prefixPerm != null) {
7935                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7936                 removeUriPermissionIfNeededLocked(prefixPerm);
7937             }
7938
7939             if (persistChanged) {
7940                 schedulePersistUriGrants();
7941             }
7942         }
7943     }
7944
7945     /**
7946      * Prune any older {@link UriPermission} for the given UID until outstanding
7947      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7948      *
7949      * @return if any mutations occured that require persisting.
7950      */
7951     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7952         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7953         if (perms == null) return false;
7954         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7955
7956         final ArrayList<UriPermission> persisted = Lists.newArrayList();
7957         for (UriPermission perm : perms.values()) {
7958             if (perm.persistedModeFlags != 0) {
7959                 persisted.add(perm);
7960             }
7961         }
7962
7963         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7964         if (trimCount <= 0) return false;
7965
7966         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7967         for (int i = 0; i < trimCount; i++) {
7968             final UriPermission perm = persisted.get(i);
7969
7970             if (DEBUG_URI_PERMISSION) {
7971                 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7972             }
7973
7974             perm.releasePersistableModes(~0);
7975             removeUriPermissionIfNeededLocked(perm);
7976         }
7977
7978         return true;
7979     }
7980
7981     @Override
7982     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7983             String packageName, boolean incoming) {
7984         enforceNotIsolatedCaller("getPersistedUriPermissions");
7985         Preconditions.checkNotNull(packageName, "packageName");
7986
7987         final int callingUid = Binder.getCallingUid();
7988         final IPackageManager pm = AppGlobals.getPackageManager();
7989         try {
7990             final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7991             if (packageUid != callingUid) {
7992                 throw new SecurityException(
7993                         "Package " + packageName + " does not belong to calling UID " + callingUid);
7994             }
7995         } catch (RemoteException e) {
7996             throw new SecurityException("Failed to verify package name ownership");
7997         }
7998
7999         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8000         synchronized (this) {
8001             if (incoming) {
8002                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8003                         callingUid);
8004                 if (perms == null) {
8005                     Slog.w(TAG, "No permission grants found for " + packageName);
8006                 } else {
8007                     for (UriPermission perm : perms.values()) {
8008                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8009                             result.add(perm.buildPersistedPublicApiObject());
8010                         }
8011                     }
8012                 }
8013             } else {
8014                 final int size = mGrantedUriPermissions.size();
8015                 for (int i = 0; i < size; i++) {
8016                     final ArrayMap<GrantUri, UriPermission> perms =
8017                             mGrantedUriPermissions.valueAt(i);
8018                     for (UriPermission perm : perms.values()) {
8019                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8020                             result.add(perm.buildPersistedPublicApiObject());
8021                         }
8022                     }
8023                 }
8024             }
8025         }
8026         return new ParceledListSlice<android.content.UriPermission>(result);
8027     }
8028
8029     @Override
8030     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8031         synchronized (this) {
8032             ProcessRecord app =
8033                 who != null ? getRecordForAppLocked(who) : null;
8034             if (app == null) return;
8035
8036             Message msg = Message.obtain();
8037             msg.what = WAIT_FOR_DEBUGGER_MSG;
8038             msg.obj = app;
8039             msg.arg1 = waiting ? 1 : 0;
8040             mHandler.sendMessage(msg);
8041         }
8042     }
8043
8044     @Override
8045     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8046         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8047         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8048         outInfo.availMem = Process.getFreeMemory();
8049         outInfo.totalMem = Process.getTotalMemory();
8050         outInfo.threshold = homeAppMem;
8051         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8052         outInfo.hiddenAppThreshold = cachedAppMem;
8053         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8054                 ProcessList.SERVICE_ADJ);
8055         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8056                 ProcessList.VISIBLE_APP_ADJ);
8057         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8058                 ProcessList.FOREGROUND_APP_ADJ);
8059     }
8060     
8061     // =========================================================
8062     // TASK MANAGEMENT
8063     // =========================================================
8064
8065     @Override
8066     public List<IAppTask> getAppTasks(String callingPackage) {
8067         int callingUid = Binder.getCallingUid();
8068         long ident = Binder.clearCallingIdentity();
8069
8070         synchronized(this) {
8071             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8072             try {
8073                 if (localLOGV) Slog.v(TAG, "getAppTasks");
8074
8075                 final int N = mRecentTasks.size();
8076                 for (int i = 0; i < N; i++) {
8077                     TaskRecord tr = mRecentTasks.get(i);
8078                     // Skip tasks that do not match the caller.  We don't need to verify
8079                     // callingPackage, because we are also limiting to callingUid and know
8080                     // that will limit to the correct security sandbox.
8081                     if (tr.effectiveUid != callingUid) {
8082                         continue;
8083                     }
8084                     Intent intent = tr.getBaseIntent();
8085                     if (intent == null ||
8086                             !callingPackage.equals(intent.getComponent().getPackageName())) {
8087                         continue;
8088                     }
8089                     ActivityManager.RecentTaskInfo taskInfo =
8090                             createRecentTaskInfoFromTaskRecord(tr);
8091                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8092                     list.add(taskImpl);
8093                 }
8094             } finally {
8095                 Binder.restoreCallingIdentity(ident);
8096             }
8097             return list;
8098         }
8099     }
8100
8101     @Override
8102     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8103         final int callingUid = Binder.getCallingUid();
8104         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8105
8106         synchronized(this) {
8107             if (localLOGV) Slog.v(
8108                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8109
8110             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8111                     callingUid);
8112
8113             // TODO: Improve with MRU list from all ActivityStacks.
8114             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8115         }
8116
8117         return list;
8118     }
8119
8120     /**
8121      * Creates a new RecentTaskInfo from a TaskRecord.
8122      */
8123     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8124         // Update the task description to reflect any changes in the task stack
8125         tr.updateTaskDescription();
8126
8127         // Compose the recent task info
8128         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8129         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8130         rti.persistentId = tr.taskId;
8131         rti.baseIntent = new Intent(tr.getBaseIntent());
8132         rti.origActivity = tr.origActivity;
8133         rti.description = tr.lastDescription;
8134         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8135         rti.userId = tr.userId;
8136         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8137         rti.firstActiveTime = tr.firstActiveTime;
8138         rti.lastActiveTime = tr.lastActiveTime;
8139         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8140         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8141         return rti;
8142     }
8143
8144     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8145         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8146                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8147         if (!allowed) {
8148             if (checkPermission(android.Manifest.permission.GET_TASKS,
8149                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8150                 // Temporary compatibility: some existing apps on the system image may
8151                 // still be requesting the old permission and not switched to the new
8152                 // one; if so, we'll still allow them full access.  This means we need
8153                 // to see if they are holding the old permission and are a system app.
8154                 try {
8155                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8156                         allowed = true;
8157                         Slog.w(TAG, caller + ": caller " + callingUid
8158                                 + " is using old GET_TASKS but privileged; allowing");
8159                     }
8160                 } catch (RemoteException e) {
8161                 }
8162             }
8163         }
8164         if (!allowed) {
8165             Slog.w(TAG, caller + ": caller " + callingUid
8166                     + " does not hold REAL_GET_TASKS; limiting output");
8167         }
8168         return allowed;
8169     }
8170
8171     @Override
8172     public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8173         final int callingUid = Binder.getCallingUid();
8174         userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8175                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8176
8177         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8178         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8179         synchronized (this) {
8180             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8181                     callingUid);
8182             final boolean detailed = checkCallingPermission(
8183                     android.Manifest.permission.GET_DETAILED_TASKS)
8184                     == PackageManager.PERMISSION_GRANTED;
8185
8186             final int N = mRecentTasks.size();
8187             ArrayList<ActivityManager.RecentTaskInfo> res
8188                     = new ArrayList<ActivityManager.RecentTaskInfo>(
8189                             maxNum < N ? maxNum : N);
8190
8191             final Set<Integer> includedUsers;
8192             if (includeProfiles) {
8193                 includedUsers = getProfileIdsLocked(userId);
8194             } else {
8195                 includedUsers = new HashSet<Integer>();
8196             }
8197             includedUsers.add(Integer.valueOf(userId));
8198
8199             for (int i=0; i<N && maxNum > 0; i++) {
8200                 TaskRecord tr = mRecentTasks.get(i);
8201                 // Only add calling user or related users recent tasks
8202                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8203                     if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8204                     continue;
8205                 }
8206
8207                 // Return the entry if desired by the caller.  We always return
8208                 // the first entry, because callers always expect this to be the
8209                 // foreground app.  We may filter others if the caller has
8210                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8211                 // we should exclude the entry.
8212
8213                 if (i == 0
8214                         || withExcluded
8215                         || (tr.intent == null)
8216                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8217                                 == 0)) {
8218                     if (!allowed) {
8219                         // If the caller doesn't have the GET_TASKS permission, then only
8220                         // allow them to see a small subset of tasks -- their own and home.
8221                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8222                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8223                             continue;
8224                         }
8225                     }
8226                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8227                         if (tr.stack != null && tr.stack.isHomeStack()) {
8228                             if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8229                             continue;
8230                         }
8231                     }
8232                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8233                         // Don't include auto remove tasks that are finished or finishing.
8234                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8235                                 + tr);
8236                         continue;
8237                     }
8238                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8239                             && !tr.isAvailable) {
8240                         if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8241                         continue;
8242                     }
8243
8244                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8245                     if (!detailed) {
8246                         rti.baseIntent.replaceExtras((Bundle)null);
8247                     }
8248
8249                     res.add(rti);
8250                     maxNum--;
8251                 }
8252             }
8253             return res;
8254         }
8255     }
8256
8257     TaskRecord recentTaskForIdLocked(int id) {
8258         final int N = mRecentTasks.size();
8259             for (int i=0; i<N; i++) {
8260                 TaskRecord tr = mRecentTasks.get(i);
8261                 if (tr.taskId == id) {
8262                     return tr;
8263                 }
8264             }
8265             return null;
8266     }
8267
8268     @Override
8269     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8270         synchronized (this) {
8271             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8272                     "getTaskThumbnail()");
8273             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8274             if (tr != null) {
8275                 return tr.getTaskThumbnailLocked();
8276             }
8277         }
8278         return null;
8279     }
8280
8281     @Override
8282     public int addAppTask(IBinder activityToken, Intent intent,
8283             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8284         final int callingUid = Binder.getCallingUid();
8285         final long callingIdent = Binder.clearCallingIdentity();
8286
8287         try {
8288             synchronized (this) {
8289                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8290                 if (r == null) {
8291                     throw new IllegalArgumentException("Activity does not exist; token="
8292                             + activityToken);
8293                 }
8294                 ComponentName comp = intent.getComponent();
8295                 if (comp == null) {
8296                     throw new IllegalArgumentException("Intent " + intent
8297                             + " must specify explicit component");
8298                 }
8299                 if (thumbnail.getWidth() != mThumbnailWidth
8300                         || thumbnail.getHeight() != mThumbnailHeight) {
8301                     throw new IllegalArgumentException("Bad thumbnail size: got "
8302                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8303                             + mThumbnailWidth + "x" + mThumbnailHeight);
8304                 }
8305                 if (intent.getSelector() != null) {
8306                     intent.setSelector(null);
8307                 }
8308                 if (intent.getSourceBounds() != null) {
8309                     intent.setSourceBounds(null);
8310                 }
8311                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8312                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8313                         // The caller has added this as an auto-remove task...  that makes no
8314                         // sense, so turn off auto-remove.
8315                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8316                     }
8317                 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8318                     // Must be a new task.
8319                     intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8320                 }
8321                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8322                     mLastAddedTaskActivity = null;
8323                 }
8324                 ActivityInfo ainfo = mLastAddedTaskActivity;
8325                 if (ainfo == null) {
8326                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8327                             comp, 0, UserHandle.getUserId(callingUid));
8328                     if (ainfo.applicationInfo.uid != callingUid) {
8329                         throw new SecurityException(
8330                                 "Can't add task for another application: target uid="
8331                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8332                     }
8333                 }
8334
8335                 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8336                         intent, description);
8337
8338                 int trimIdx = trimRecentsForTaskLocked(task, false);
8339                 if (trimIdx >= 0) {
8340                     // If this would have caused a trim, then we'll abort because that
8341                     // means it would be added at the end of the list but then just removed.
8342                     return INVALID_TASK_ID;
8343                 }
8344
8345                 final int N = mRecentTasks.size();
8346                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8347                     final TaskRecord tr = mRecentTasks.remove(N - 1);
8348                     tr.removedFromRecents();
8349                 }
8350
8351                 task.inRecents = true;
8352                 mRecentTasks.add(task);
8353                 r.task.stack.addTask(task, false, false);
8354
8355                 task.setLastThumbnail(thumbnail);
8356                 task.freeLastThumbnail();
8357
8358                 return task.taskId;
8359             }
8360         } finally {
8361             Binder.restoreCallingIdentity(callingIdent);
8362         }
8363     }
8364
8365     @Override
8366     public Point getAppTaskThumbnailSize() {
8367         synchronized (this) {
8368             return new Point(mThumbnailWidth,  mThumbnailHeight);
8369         }
8370     }
8371
8372     @Override
8373     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8374         synchronized (this) {
8375             ActivityRecord r = ActivityRecord.isInStackLocked(token);
8376             if (r != null) {
8377                 r.setTaskDescription(td);
8378                 r.task.updateTaskDescription();
8379             }
8380         }
8381     }
8382
8383     @Override
8384     public Bitmap getTaskDescriptionIcon(String filename) {
8385         if (!FileUtils.isValidExtFilename(filename)
8386                 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8387             throw new IllegalArgumentException("Bad filename: " + filename);
8388         }
8389         return mTaskPersister.getTaskDescriptionIcon(filename);
8390     }
8391
8392     @Override
8393     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8394             throws RemoteException {
8395         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8396                 opts.getCustomInPlaceResId() == 0) {
8397             throw new IllegalArgumentException("Expected in-place ActivityOption " +
8398                     "with valid animation");
8399         }
8400         mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8401         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8402                 opts.getCustomInPlaceResId());
8403         mWindowManager.executeAppTransition();
8404     }
8405
8406     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8407         mRecentTasks.remove(tr);
8408         tr.removedFromRecents();
8409         ComponentName component = tr.getBaseIntent().getComponent();
8410         if (component == null) {
8411             Slog.w(TAG, "No component for base intent of task: " + tr);
8412             return;
8413         }
8414
8415         if (!killProcess) {
8416             return;
8417         }
8418
8419         // Determine if the process(es) for this task should be killed.
8420         final String pkg = component.getPackageName();
8421         ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8422         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8423         for (int i = 0; i < pmap.size(); i++) {
8424
8425             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8426             for (int j = 0; j < uids.size(); j++) {
8427                 ProcessRecord proc = uids.valueAt(j);
8428                 if (proc.userId != tr.userId) {
8429                     // Don't kill process for a different user.
8430                     continue;
8431                 }
8432                 if (proc == mHomeProcess) {
8433                     // Don't kill the home process along with tasks from the same package.
8434                     continue;
8435                 }
8436                 if (!proc.pkgList.containsKey(pkg)) {
8437                     // Don't kill process that is not associated with this task.
8438                     continue;
8439                 }
8440
8441                 for (int k = 0; k < proc.activities.size(); k++) {
8442                     TaskRecord otherTask = proc.activities.get(k).task;
8443                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8444                         // Don't kill process(es) that has an activity in a different task that is
8445                         // also in recents.
8446                         return;
8447                     }
8448                 }
8449
8450                 // Add process to kill list.
8451                 procsToKill.add(proc);
8452             }
8453         }
8454
8455         // Find any running services associated with this app and stop if needed.
8456         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8457
8458         // Kill the running processes.
8459         for (int i = 0; i < procsToKill.size(); i++) {
8460             ProcessRecord pr = procsToKill.get(i);
8461             if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8462                 pr.kill("remove task", true);
8463             } else {
8464                 pr.waitingToKill = "remove task";
8465             }
8466         }
8467     }
8468
8469     private void removeTasksByPackageNameLocked(String packageName, int userId) {
8470         // Remove all tasks with activities in the specified package from the list of recent tasks
8471         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8472             TaskRecord tr = mRecentTasks.get(i);
8473             if (tr.userId != userId) continue;
8474
8475             ComponentName cn = tr.intent.getComponent();
8476             if (cn != null && cn.getPackageName().equals(packageName)) {
8477                 // If the package name matches, remove the task.
8478                 removeTaskByIdLocked(tr.taskId, true);
8479             }
8480         }
8481     }
8482
8483     private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8484         final IPackageManager pm = AppGlobals.getPackageManager();
8485         final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8486
8487         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8488             TaskRecord tr = mRecentTasks.get(i);
8489             if (tr.userId != userId) continue;
8490
8491             ComponentName cn = tr.intent.getComponent();
8492             if (cn != null && cn.getPackageName().equals(packageName)) {
8493                 // Skip if component still exists in the package.
8494                 if (componentsKnownToExist.contains(cn)) continue;
8495
8496                 try {
8497                     ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8498                     if (info != null) {
8499                         componentsKnownToExist.add(cn);
8500                     } else {
8501                         removeTaskByIdLocked(tr.taskId, false);
8502                     }
8503                 } catch (RemoteException e) {
8504                     Log.e(TAG, "Activity info query failed. component=" + cn, e);
8505                 }
8506             }
8507         }
8508     }
8509
8510     /**
8511      * Removes the task with the specified task id.
8512      *
8513      * @param taskId Identifier of the task to be removed.
8514      * @param killProcess Kill any process associated with the task if possible.
8515      * @return Returns true if the given task was found and removed.
8516      */
8517     private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8518         TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8519         if (tr != null) {
8520             tr.removeTaskActivitiesLocked();
8521             cleanUpRemovedTaskLocked(tr, killProcess);
8522             if (tr.isPersistable) {
8523                 notifyTaskPersisterLocked(null, true);
8524             }
8525             return true;
8526         }
8527         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8528         return false;
8529     }
8530
8531     @Override
8532     public boolean removeTask(int taskId) {
8533         synchronized (this) {
8534             enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8535                     "removeTask()");
8536             long ident = Binder.clearCallingIdentity();
8537             try {
8538                 return removeTaskByIdLocked(taskId, true);
8539             } finally {
8540                 Binder.restoreCallingIdentity(ident);
8541             }
8542         }
8543     }
8544
8545     /**
8546      * TODO: Add mController hook
8547      */
8548     @Override
8549     public void moveTaskToFront(int taskId, int flags, Bundle options) {
8550         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8551                 "moveTaskToFront()");
8552
8553         if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8554         synchronized(this) {
8555             moveTaskToFrontLocked(taskId, flags, options);
8556         }
8557     }
8558
8559     void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8560         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8561                 Binder.getCallingUid(), -1, -1, "Task to front")) {
8562             ActivityOptions.abort(options);
8563             return;
8564         }
8565         final long origId = Binder.clearCallingIdentity();
8566         try {
8567             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8568             if (task == null) {
8569                 Slog.d(TAG, "Could not find task for id: "+ taskId);
8570                 return;
8571             }
8572             if (mStackSupervisor.isLockTaskModeViolation(task)) {
8573                 mStackSupervisor.showLockTaskToast();
8574                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8575                 return;
8576             }
8577             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8578             if (prev != null && prev.isRecentsActivity()) {
8579                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8580             }
8581             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8582         } finally {
8583             Binder.restoreCallingIdentity(origId);
8584         }
8585         ActivityOptions.abort(options);
8586     }
8587
8588     @Override
8589     public void moveTaskToBack(int taskId) {
8590         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8591                 "moveTaskToBack()");
8592
8593         synchronized(this) {
8594             TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8595             if (tr != null) {
8596                 if (tr == mStackSupervisor.mLockTaskModeTask) {
8597                     mStackSupervisor.showLockTaskToast();
8598                     return;
8599                 }
8600                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8601                 ActivityStack stack = tr.stack;
8602                 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8603                     if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8604                             Binder.getCallingUid(), -1, -1, "Task to back")) {
8605                         return;
8606                     }
8607                 }
8608                 final long origId = Binder.clearCallingIdentity();
8609                 try {
8610                     stack.moveTaskToBackLocked(taskId);
8611                 } finally {
8612                     Binder.restoreCallingIdentity(origId);
8613                 }
8614             }
8615         }
8616     }
8617
8618     /**
8619      * Moves an activity, and all of the other activities within the same task, to the bottom
8620      * of the history stack.  The activity's order within the task is unchanged.
8621      * 
8622      * @param token A reference to the activity we wish to move
8623      * @param nonRoot If false then this only works if the activity is the root
8624      *                of a task; if true it will work for any activity in a task.
8625      * @return Returns true if the move completed, false if not.
8626      */
8627     @Override
8628     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8629         enforceNotIsolatedCaller("moveActivityTaskToBack");
8630         synchronized(this) {
8631             final long origId = Binder.clearCallingIdentity();
8632             try {
8633                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8634                 if (taskId >= 0) {
8635                     if ((mStackSupervisor.mLockTaskModeTask != null)
8636                             && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8637                         mStackSupervisor.showLockTaskToast();
8638                         return false;
8639                     }
8640                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8641                 }
8642             } finally {
8643                 Binder.restoreCallingIdentity(origId);
8644             }
8645         }
8646         return false;
8647     }
8648
8649     @Override
8650     public void moveTaskBackwards(int task) {
8651         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8652                 "moveTaskBackwards()");
8653
8654         synchronized(this) {
8655             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8656                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
8657                 return;
8658             }
8659             final long origId = Binder.clearCallingIdentity();
8660             moveTaskBackwardsLocked(task);
8661             Binder.restoreCallingIdentity(origId);
8662         }
8663     }
8664
8665     private final void moveTaskBackwardsLocked(int task) {
8666         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8667     }
8668
8669     @Override
8670     public IBinder getHomeActivityToken() throws RemoteException {
8671         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8672                 "getHomeActivityToken()");
8673         synchronized (this) {
8674             return mStackSupervisor.getHomeActivityToken();
8675         }
8676     }
8677
8678     @Override
8679     public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8680             IActivityContainerCallback callback) throws RemoteException {
8681         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8682                 "createActivityContainer()");
8683         synchronized (this) {
8684             if (parentActivityToken == null) {
8685                 throw new IllegalArgumentException("parent token must not be null");
8686             }
8687             ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8688             if (r == null) {
8689                 return null;
8690             }
8691             if (callback == null) {
8692                 throw new IllegalArgumentException("callback must not be null");
8693             }
8694             return mStackSupervisor.createActivityContainer(r, callback);
8695         }
8696     }
8697
8698     @Override
8699     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8700         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                 "deleteActivityContainer()");
8702         synchronized (this) {
8703             mStackSupervisor.deleteActivityContainer(container);
8704         }
8705     }
8706
8707     @Override
8708     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8709         synchronized (this) {
8710             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8711             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8712                 return stack.mActivityContainer.getDisplayId();
8713             }
8714             return Display.DEFAULT_DISPLAY;
8715         }
8716     }
8717
8718     @Override
8719     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8720         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8721                 "moveTaskToStack()");
8722         if (stackId == HOME_STACK_ID) {
8723             Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8724                     new RuntimeException("here").fillInStackTrace());
8725         }
8726         synchronized (this) {
8727             long ident = Binder.clearCallingIdentity();
8728             try {
8729                 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8730                         + stackId + " toTop=" + toTop);
8731                 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8732             } finally {
8733                 Binder.restoreCallingIdentity(ident);
8734             }
8735         }
8736     }
8737
8738     @Override
8739     public void resizeStack(int stackBoxId, Rect bounds) {
8740         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8741                 "resizeStackBox()");
8742         long ident = Binder.clearCallingIdentity();
8743         try {
8744             mWindowManager.resizeStack(stackBoxId, bounds);
8745         } finally {
8746             Binder.restoreCallingIdentity(ident);
8747         }
8748     }
8749
8750     @Override
8751     public List<StackInfo> getAllStackInfos() {
8752         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8753                 "getAllStackInfos()");
8754         long ident = Binder.clearCallingIdentity();
8755         try {
8756             synchronized (this) {
8757                 return mStackSupervisor.getAllStackInfosLocked();
8758             }
8759         } finally {
8760             Binder.restoreCallingIdentity(ident);
8761         }
8762     }
8763
8764     @Override
8765     public StackInfo getStackInfo(int stackId) {
8766         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8767                 "getStackInfo()");
8768         long ident = Binder.clearCallingIdentity();
8769         try {
8770             synchronized (this) {
8771                 return mStackSupervisor.getStackInfoLocked(stackId);
8772             }
8773         } finally {
8774             Binder.restoreCallingIdentity(ident);
8775         }
8776     }
8777
8778     @Override
8779     public boolean isInHomeStack(int taskId) {
8780         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8781                 "getStackInfo()");
8782         long ident = Binder.clearCallingIdentity();
8783         try {
8784             synchronized (this) {
8785                 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8786                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8787             }
8788         } finally {
8789             Binder.restoreCallingIdentity(ident);
8790         }
8791     }
8792
8793     @Override
8794     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8795         synchronized(this) {
8796             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8797         }
8798     }
8799
8800     private boolean isLockTaskAuthorized(String pkg) {
8801         final DevicePolicyManager dpm = (DevicePolicyManager)
8802                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8803         try {
8804             int uid = mContext.getPackageManager().getPackageUid(pkg,
8805                     Binder.getCallingUserHandle().getIdentifier());
8806             return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8807         } catch (NameNotFoundException e) {
8808             return false;
8809         }
8810     }
8811
8812     void startLockTaskMode(TaskRecord task) {
8813         final String pkg;
8814         synchronized (this) {
8815             pkg = task.intent.getComponent().getPackageName();
8816         }
8817         boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8818         if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8819             StatusBarManagerInternal statusBarManager = LocalServices.getService(
8820                     StatusBarManagerInternal.class);
8821             if (statusBarManager != null) {
8822                 statusBarManager.showScreenPinningRequest();
8823             }
8824             return;
8825         }
8826         long ident = Binder.clearCallingIdentity();
8827         try {
8828             synchronized (this) {
8829                 // Since we lost lock on task, make sure it is still there.
8830                 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8831                 if (task != null) {
8832                     if (!isSystemInitiated
8833                             && ((mStackSupervisor.getFocusedStack() == null)
8834                                     || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8835                         throw new IllegalArgumentException("Invalid task, not in foreground");
8836                     }
8837                     mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8838                             "startLockTask");
8839                 }
8840             }
8841         } finally {
8842             Binder.restoreCallingIdentity(ident);
8843         }
8844     }
8845
8846     @Override
8847     public void startLockTaskMode(int taskId) {
8848         final TaskRecord task;
8849         long ident = Binder.clearCallingIdentity();
8850         try {
8851             synchronized (this) {
8852                 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8853             }
8854         } finally {
8855             Binder.restoreCallingIdentity(ident);
8856         }
8857         if (task != null) {
8858             startLockTaskMode(task);
8859         }
8860     }
8861
8862     @Override
8863     public void startLockTaskMode(IBinder token) {
8864         final TaskRecord task;
8865         long ident = Binder.clearCallingIdentity();
8866         try {
8867             synchronized (this) {
8868                 final ActivityRecord r = ActivityRecord.forToken(token);
8869                 if (r == null) {
8870                     return;
8871                 }
8872                 task = r.task;
8873             }
8874         } finally {
8875             Binder.restoreCallingIdentity(ident);
8876         }
8877         if (task != null) {
8878             startLockTaskMode(task);
8879         }
8880     }
8881
8882     @Override
8883     public void startLockTaskModeOnCurrent() throws RemoteException {
8884         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8885                 "startLockTaskModeOnCurrent");
8886         long ident = Binder.clearCallingIdentity();
8887         try {
8888             ActivityRecord r = null;
8889             synchronized (this) {
8890                 r = mStackSupervisor.topRunningActivityLocked();
8891             }
8892             startLockTaskMode(r.task);
8893         } finally {
8894             Binder.restoreCallingIdentity(ident);
8895         }
8896     }
8897
8898     @Override
8899     public void stopLockTaskMode() {
8900         // Verify that the user matches the package of the intent for the TaskRecord
8901         // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8902         // and stopLockTaskMode.
8903         final int callingUid = Binder.getCallingUid();
8904         if (callingUid != Process.SYSTEM_UID) {
8905             try {
8906                 String pkg =
8907                         mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8908                 int uid = mContext.getPackageManager().getPackageUid(pkg,
8909                         Binder.getCallingUserHandle().getIdentifier());
8910                 if (uid != callingUid) {
8911                     throw new SecurityException("Invalid uid, expected " + uid);
8912                 }
8913             } catch (NameNotFoundException e) {
8914                 Log.d(TAG, "stopLockTaskMode " + e);
8915                 return;
8916             }
8917         }
8918         long ident = Binder.clearCallingIdentity();
8919         try {
8920             Log.d(TAG, "stopLockTaskMode");
8921             // Stop lock task
8922             synchronized (this) {
8923                 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8924             }
8925         } finally {
8926             Binder.restoreCallingIdentity(ident);
8927         }
8928     }
8929
8930     @Override
8931     public void stopLockTaskModeOnCurrent() throws RemoteException {
8932         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8933                 "stopLockTaskModeOnCurrent");
8934         long ident = Binder.clearCallingIdentity();
8935         try {
8936             stopLockTaskMode();
8937         } finally {
8938             Binder.restoreCallingIdentity(ident);
8939         }
8940     }
8941
8942     @Override
8943     public boolean isInLockTaskMode() {
8944         synchronized (this) {
8945             return mStackSupervisor.isInLockTaskMode();
8946         }
8947     }
8948
8949     // =========================================================
8950     // CONTENT PROVIDERS
8951     // =========================================================
8952
8953     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8954         List<ProviderInfo> providers = null;
8955         try {
8956             providers = AppGlobals.getPackageManager().
8957                 queryContentProviders(app.processName, app.uid,
8958                         STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8959         } catch (RemoteException ex) {
8960         }
8961         if (DEBUG_MU)
8962             Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8963         int userId = app.userId;
8964         if (providers != null) {
8965             int N = providers.size();
8966             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8967             for (int i=0; i<N; i++) {
8968                 ProviderInfo cpi =
8969                     (ProviderInfo)providers.get(i);
8970                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8971                         cpi.name, cpi.flags);
8972                 if (singleton && UserHandle.getUserId(app.uid) != 0) {
8973                     // This is a singleton provider, but a user besides the
8974                     // default user is asking to initialize a process it runs
8975                     // in...  well, no, it doesn't actually run in this process,
8976                     // it runs in the process of the default user.  Get rid of it.
8977                     providers.remove(i);
8978                     N--;
8979                     i--;
8980                     continue;
8981                 }
8982
8983                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8984                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8985                 if (cpr == null) {
8986                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8987                     mProviderMap.putProviderByClass(comp, cpr);
8988                 }
8989                 if (DEBUG_MU)
8990                     Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8991                 app.pubProviders.put(cpi.name, cpr);
8992                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8993                     // Don't add this if it is a platform component that is marked
8994                     // to run in multiple processes, because this is actually
8995                     // part of the framework so doesn't make sense to track as a
8996                     // separate apk in the process.
8997                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8998                             mProcessStats);
8999                 }
9000                 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9001             }
9002         }
9003         return providers;
9004     }
9005
9006     /**
9007      * Check if the calling UID has a possible chance at accessing the provider
9008      * at the given authority and user.
9009      */
9010     public String checkContentProviderAccess(String authority, int userId) {
9011         if (userId == UserHandle.USER_ALL) {
9012             mContext.enforceCallingOrSelfPermission(
9013                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
9014             userId = UserHandle.getCallingUserId();
9015         }
9016
9017         ProviderInfo cpi = null;
9018         try {
9019             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
9020                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9021         } catch (RemoteException ignored) {
9022         }
9023         if (cpi == null) {
9024             // TODO: make this an outright failure in a future platform release;
9025             // until then anonymous content notifications are unprotected
9026             //return "Failed to find provider " + authority + " for user " + userId;
9027             return null;
9028         }
9029
9030         ProcessRecord r = null;
9031         synchronized (mPidsSelfLocked) {
9032             r = mPidsSelfLocked.get(Binder.getCallingPid());
9033         }
9034         if (r == null) {
9035             return "Failed to find PID " + Binder.getCallingPid();
9036         }
9037
9038         synchronized (this) {
9039             return checkContentProviderPermissionLocked(cpi, r, userId, true);
9040         }
9041     }
9042
9043
9044     /**
9045      * Check if {@link ProcessRecord} has a possible chance at accessing the
9046      * given {@link ProviderInfo}. Final permission checking is always done
9047      * in {@link ContentProvider}.
9048      */
9049     private final String checkContentProviderPermissionLocked(
9050             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9051         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9052         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9053         boolean checkedGrants = false;
9054         if (checkUser) {
9055             // Looking for cross-user grants before enforcing the typical cross-users permissions
9056             int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9057             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9058                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9059                     return null;
9060                 }
9061                 checkedGrants = true;
9062             }
9063             userId = handleIncomingUser(callingPid, callingUid, userId,
9064                     false, ALLOW_NON_FULL,
9065                     "checkContentProviderPermissionLocked " + cpi.authority, null);
9066             if (userId != tmpTargetUserId) {
9067                 // When we actually went to determine the final targer user ID, this ended
9068                 // up different than our initial check for the authority.  This is because
9069                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9070                 // SELF.  So we need to re-check the grants again.
9071                 checkedGrants = false;
9072             }
9073         }
9074         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9075                 cpi.applicationInfo.uid, cpi.exported)
9076                 == PackageManager.PERMISSION_GRANTED) {
9077             return null;
9078         }
9079         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9080                 cpi.applicationInfo.uid, cpi.exported)
9081                 == PackageManager.PERMISSION_GRANTED) {
9082             return null;
9083         }
9084         
9085         PathPermission[] pps = cpi.pathPermissions;
9086         if (pps != null) {
9087             int i = pps.length;
9088             while (i > 0) {
9089                 i--;
9090                 PathPermission pp = pps[i];
9091                 String pprperm = pp.getReadPermission();
9092                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9093                         cpi.applicationInfo.uid, cpi.exported)
9094                         == PackageManager.PERMISSION_GRANTED) {
9095                     return null;
9096                 }
9097                 String ppwperm = pp.getWritePermission();
9098                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9099                         cpi.applicationInfo.uid, cpi.exported)
9100                         == PackageManager.PERMISSION_GRANTED) {
9101                     return null;
9102                 }
9103             }
9104         }
9105         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9106             return null;
9107         }
9108
9109         String msg;
9110         if (!cpi.exported) {
9111             msg = "Permission Denial: opening provider " + cpi.name
9112                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9113                     + ", uid=" + callingUid + ") that is not exported from uid "
9114                     + cpi.applicationInfo.uid;
9115         } else {
9116             msg = "Permission Denial: opening provider " + cpi.name
9117                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9118                     + ", uid=" + callingUid + ") requires "
9119                     + cpi.readPermission + " or " + cpi.writePermission;
9120         }
9121         Slog.w(TAG, msg);
9122         return msg;
9123     }
9124
9125     /**
9126      * Returns if the ContentProvider has granted a uri to callingUid
9127      */
9128     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9129         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9130         if (perms != null) {
9131             for (int i=perms.size()-1; i>=0; i--) {
9132                 GrantUri grantUri = perms.keyAt(i);
9133                 if (grantUri.sourceUserId == userId || !checkUser) {
9134                     if (matchesProvider(grantUri.uri, cpi)) {
9135                         return true;
9136                     }
9137                 }
9138             }
9139         }
9140         return false;
9141     }
9142
9143     /**
9144      * Returns true if the uri authority is one of the authorities specified in the provider.
9145      */
9146     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9147         String uriAuth = uri.getAuthority();
9148         String cpiAuth = cpi.authority;
9149         if (cpiAuth.indexOf(';') == -1) {
9150             return cpiAuth.equals(uriAuth);
9151         }
9152         String[] cpiAuths = cpiAuth.split(";");
9153         int length = cpiAuths.length;
9154         for (int i = 0; i < length; i++) {
9155             if (cpiAuths[i].equals(uriAuth)) return true;
9156         }
9157         return false;
9158     }
9159
9160     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9161             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9162         if (r != null) {
9163             for (int i=0; i<r.conProviders.size(); i++) {
9164                 ContentProviderConnection conn = r.conProviders.get(i);
9165                 if (conn.provider == cpr) {
9166                     if (DEBUG_PROVIDER) Slog.v(TAG,
9167                             "Adding provider requested by "
9168                             + r.processName + " from process "
9169                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9170                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9171                     if (stable) {
9172                         conn.stableCount++;
9173                         conn.numStableIncs++;
9174                     } else {
9175                         conn.unstableCount++;
9176                         conn.numUnstableIncs++;
9177                     }
9178                     return conn;
9179                 }
9180             }
9181             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9182             if (stable) {
9183                 conn.stableCount = 1;
9184                 conn.numStableIncs = 1;
9185             } else {
9186                 conn.unstableCount = 1;
9187                 conn.numUnstableIncs = 1;
9188             }
9189             cpr.connections.add(conn);
9190             r.conProviders.add(conn);
9191             startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9192             return conn;
9193         }
9194         cpr.addExternalProcessHandleLocked(externalProcessToken);
9195         return null;
9196     }
9197
9198     boolean decProviderCountLocked(ContentProviderConnection conn,
9199             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9200         if (conn != null) {
9201             cpr = conn.provider;
9202             if (DEBUG_PROVIDER) Slog.v(TAG,
9203                     "Removing provider requested by "
9204                     + conn.client.processName + " from process "
9205                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9206                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9207             if (stable) {
9208                 conn.stableCount--;
9209             } else {
9210                 conn.unstableCount--;
9211             }
9212             if (conn.stableCount == 0 && conn.unstableCount == 0) {
9213                 cpr.connections.remove(conn);
9214                 conn.client.conProviders.remove(conn);
9215                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9216                 return true;
9217             }
9218             return false;
9219         }
9220         cpr.removeExternalProcessHandleLocked(externalProcessToken);
9221         return false;
9222     }
9223
9224     private void checkTime(long startTime, String where) {
9225         long now = SystemClock.elapsedRealtime();
9226         if ((now-startTime) > 1000) {
9227             // If we are taking more than a second, log about it.
9228             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9229         }
9230     }
9231
9232     private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9233             String name, IBinder token, boolean stable, int userId) {
9234         ContentProviderRecord cpr;
9235         ContentProviderConnection conn = null;
9236         ProviderInfo cpi = null;
9237
9238         synchronized(this) {
9239             long startTime = SystemClock.elapsedRealtime();
9240
9241             ProcessRecord r = null;
9242             if (caller != null) {
9243                 r = getRecordForAppLocked(caller);
9244                 if (r == null) {
9245                     throw new SecurityException(
9246                             "Unable to find app for caller " + caller
9247                           + " (pid=" + Binder.getCallingPid()
9248                           + ") when getting content provider " + name);
9249                 }
9250             }
9251
9252             boolean checkCrossUser = true;
9253
9254             checkTime(startTime, "getContentProviderImpl: getProviderByName");
9255
9256             // First check if this content provider has been published...
9257             cpr = mProviderMap.getProviderByName(name, userId);
9258             // If that didn't work, check if it exists for user 0 and then
9259             // verify that it's a singleton provider before using it.
9260             if (cpr == null && userId != UserHandle.USER_OWNER) {
9261                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9262                 if (cpr != null) {
9263                     cpi = cpr.info;
9264                     if (isSingleton(cpi.processName, cpi.applicationInfo,
9265                             cpi.name, cpi.flags)
9266                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9267                         userId = UserHandle.USER_OWNER;
9268                         checkCrossUser = false;
9269                     } else {
9270                         cpr = null;
9271                         cpi = null;
9272                     }
9273                 }
9274             }
9275
9276             boolean providerRunning = cpr != null;
9277             if (providerRunning) {
9278                 cpi = cpr.info;
9279                 String msg;
9280                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9281                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9282                         != null) {
9283                     throw new SecurityException(msg);
9284                 }
9285                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9286
9287                 if (r != null && cpr.canRunHere(r)) {
9288                     // This provider has been published or is in the process
9289                     // of being published...  but it is also allowed to run
9290                     // in the caller's process, so don't make a connection
9291                     // and just let the caller instantiate its own instance.
9292                     ContentProviderHolder holder = cpr.newHolder(null);
9293                     // don't give caller the provider object, it needs
9294                     // to make its own.
9295                     holder.provider = null;
9296                     return holder;
9297                 }
9298
9299                 final long origId = Binder.clearCallingIdentity();
9300
9301                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9302
9303                 // In this case the provider instance already exists, so we can
9304                 // return it right away.
9305                 conn = incProviderCountLocked(r, cpr, token, stable);
9306                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9307                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9308                         // If this is a perceptible app accessing the provider,
9309                         // make sure to count it as being accessed and thus
9310                         // back up on the LRU list.  This is good because
9311                         // content providers are often expensive to start.
9312                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9313                         updateLruProcessLocked(cpr.proc, false, null);
9314                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9315                     }
9316                 }
9317
9318                 if (cpr.proc != null) {
9319                     if (false) {
9320                         if (cpr.name.flattenToShortString().equals(
9321                                 "com.android.providers.calendar/.CalendarProvider2")) {
9322                             Slog.v(TAG, "****************** KILLING "
9323                                 + cpr.name.flattenToShortString());
9324                             Process.killProcess(cpr.proc.pid);
9325                         }
9326                     }
9327                     checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9328                     boolean success = updateOomAdjLocked(cpr.proc);
9329                     checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9330                     if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9331                     // NOTE: there is still a race here where a signal could be
9332                     // pending on the process even though we managed to update its
9333                     // adj level.  Not sure what to do about this, but at least
9334                     // the race is now smaller.
9335                     if (!success) {
9336                         // Uh oh...  it looks like the provider's process
9337                         // has been killed on us.  We need to wait for a new
9338                         // process to be started, and make sure its death
9339                         // doesn't kill our process.
9340                         Slog.i(TAG,
9341                                 "Existing provider " + cpr.name.flattenToShortString()
9342                                 + " is crashing; detaching " + r);
9343                         boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9344                         checkTime(startTime, "getContentProviderImpl: before appDied");
9345                         appDiedLocked(cpr.proc);
9346                         checkTime(startTime, "getContentProviderImpl: after appDied");
9347                         if (!lastRef) {
9348                             // This wasn't the last ref our process had on
9349                             // the provider...  we have now been killed, bail.
9350                             return null;
9351                         }
9352                         providerRunning = false;
9353                         conn = null;
9354                     }
9355                 }
9356
9357                 Binder.restoreCallingIdentity(origId);
9358             }
9359
9360             boolean singleton;
9361             if (!providerRunning) {
9362                 try {
9363                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9364                     cpi = AppGlobals.getPackageManager().
9365                         resolveContentProvider(name,
9366                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9367                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9368                 } catch (RemoteException ex) {
9369                 }
9370                 if (cpi == null) {
9371                     return null;
9372                 }
9373                 // If the provider is a singleton AND
9374                 // (it's a call within the same user || the provider is a
9375                 // privileged app)
9376                 // Then allow connecting to the singleton provider
9377                 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9378                         cpi.name, cpi.flags)
9379                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9380                 if (singleton) {
9381                     userId = UserHandle.USER_OWNER;
9382                 }
9383                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9384                 checkTime(startTime, "getContentProviderImpl: got app info for user");
9385
9386                 String msg;
9387                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9388                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9389                         != null) {
9390                     throw new SecurityException(msg);
9391                 }
9392                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9393
9394                 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9395                         && !cpi.processName.equals("system")) {
9396                     // If this content provider does not run in the system
9397                     // process, and the system is not yet ready to run other
9398                     // processes, then fail fast instead of hanging.
9399                     throw new IllegalArgumentException(
9400                             "Attempt to launch content provider before system ready");
9401                 }
9402
9403                 // Make sure that the user who owns this provider is running.  If not,
9404                 // we don't want to allow it to run.
9405                 if (!isUserRunningLocked(userId, false)) {
9406                     Slog.w(TAG, "Unable to launch app "
9407                             + cpi.applicationInfo.packageName + "/"
9408                             + cpi.applicationInfo.uid + " for provider "
9409                             + name + ": user " + userId + " is stopped");
9410                     return null;
9411                 }
9412
9413                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9414                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9415                 cpr = mProviderMap.getProviderByClass(comp, userId);
9416                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9417                 final boolean firstClass = cpr == null;
9418                 if (firstClass) {
9419                     final long ident = Binder.clearCallingIdentity();
9420                     try {
9421                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9422                         ApplicationInfo ai =
9423                             AppGlobals.getPackageManager().
9424                                 getApplicationInfo(
9425                                         cpi.applicationInfo.packageName,
9426                                         STOCK_PM_FLAGS, userId);
9427                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9428                         if (ai == null) {
9429                             Slog.w(TAG, "No package info for content provider "
9430                                     + cpi.name);
9431                             return null;
9432                         }
9433                         ai = getAppInfoForUser(ai, userId);
9434                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9435                     } catch (RemoteException ex) {
9436                         // pm is in same process, this will never happen.
9437                     } finally {
9438                         Binder.restoreCallingIdentity(ident);
9439                     }
9440                 }
9441
9442                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9443
9444                 if (r != null && cpr.canRunHere(r)) {
9445                     // If this is a multiprocess provider, then just return its
9446                     // info and allow the caller to instantiate it.  Only do
9447                     // this if the provider is the same user as the caller's
9448                     // process, or can run as root (so can be in any process).
9449                     return cpr.newHolder(null);
9450                 }
9451
9452                 if (DEBUG_PROVIDER) {
9453                     RuntimeException e = new RuntimeException("here");
9454                     Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9455                           + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9456                 }
9457
9458                 // This is single process, and our app is now connecting to it.
9459                 // See if we are already in the process of launching this
9460                 // provider.
9461                 final int N = mLaunchingProviders.size();
9462                 int i;
9463                 for (i=0; i<N; i++) {
9464                     if (mLaunchingProviders.get(i) == cpr) {
9465                         break;
9466                     }
9467                 }
9468
9469                 // If the provider is not already being launched, then get it
9470                 // started.
9471                 if (i >= N) {
9472                     final long origId = Binder.clearCallingIdentity();
9473
9474                     try {
9475                         // Content provider is now in use, its package can't be stopped.
9476                         try {
9477                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
9478                             AppGlobals.getPackageManager().setPackageStoppedState(
9479                                     cpr.appInfo.packageName, false, userId);
9480                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
9481                         } catch (RemoteException e) {
9482                         } catch (IllegalArgumentException e) {
9483                             Slog.w(TAG, "Failed trying to unstop package "
9484                                     + cpr.appInfo.packageName + ": " + e);
9485                         }
9486
9487                         // Use existing process if already started
9488                         checkTime(startTime, "getContentProviderImpl: looking for process record");
9489                         ProcessRecord proc = getProcessRecordLocked(
9490                                 cpi.processName, cpr.appInfo.uid, false);
9491                         if (proc != null && proc.thread != null) {
9492                             if (DEBUG_PROVIDER) {
9493                                 Slog.d(TAG, "Installing in existing process " + proc);
9494                             }
9495                             checkTime(startTime, "getContentProviderImpl: scheduling install");
9496                             proc.pubProviders.put(cpi.name, cpr);
9497                             try {
9498                                 proc.thread.scheduleInstallProvider(cpi);
9499                             } catch (RemoteException e) {
9500                             }
9501                         } else {
9502                             checkTime(startTime, "getContentProviderImpl: before start process");
9503                             proc = startProcessLocked(cpi.processName,
9504                                     cpr.appInfo, false, 0, "content provider",
9505                                     new ComponentName(cpi.applicationInfo.packageName,
9506                                             cpi.name), false, false, false);
9507                             checkTime(startTime, "getContentProviderImpl: after start process");
9508                             if (proc == null) {
9509                                 Slog.w(TAG, "Unable to launch app "
9510                                         + cpi.applicationInfo.packageName + "/"
9511                                         + cpi.applicationInfo.uid + " for provider "
9512                                         + name + ": process is bad");
9513                                 return null;
9514                             }
9515                         }
9516                         cpr.launchingApp = proc;
9517                         mLaunchingProviders.add(cpr);
9518                     } finally {
9519                         Binder.restoreCallingIdentity(origId);
9520                     }
9521                 }
9522
9523                 checkTime(startTime, "getContentProviderImpl: updating data structures");
9524
9525                 // Make sure the provider is published (the same provider class
9526                 // may be published under multiple names).
9527                 if (firstClass) {
9528                     mProviderMap.putProviderByClass(comp, cpr);
9529                 }
9530
9531                 mProviderMap.putProviderByName(name, cpr);
9532                 conn = incProviderCountLocked(r, cpr, token, stable);
9533                 if (conn != null) {
9534                     conn.waiting = true;
9535                 }
9536             }
9537             checkTime(startTime, "getContentProviderImpl: done!");
9538         }
9539
9540         // Wait for the provider to be published...
9541         synchronized (cpr) {
9542             while (cpr.provider == null) {
9543                 if (cpr.launchingApp == null) {
9544                     Slog.w(TAG, "Unable to launch app "
9545                             + cpi.applicationInfo.packageName + "/"
9546                             + cpi.applicationInfo.uid + " for provider "
9547                             + name + ": launching app became null");
9548                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9549                             UserHandle.getUserId(cpi.applicationInfo.uid),
9550                             cpi.applicationInfo.packageName,
9551                             cpi.applicationInfo.uid, name);
9552                     return null;
9553                 }
9554                 try {
9555                     if (DEBUG_MU) {
9556                         Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9557                                 + cpr.launchingApp);
9558                     }
9559                     if (conn != null) {
9560                         conn.waiting = true;
9561                     }
9562                     cpr.wait();
9563                 } catch (InterruptedException ex) {
9564                 } finally {
9565                     if (conn != null) {
9566                         conn.waiting = false;
9567                     }
9568                 }
9569             }
9570         }
9571         return cpr != null ? cpr.newHolder(conn) : null;
9572     }
9573
9574     @Override
9575     public final ContentProviderHolder getContentProvider(
9576             IApplicationThread caller, String name, int userId, boolean stable) {
9577         enforceNotIsolatedCaller("getContentProvider");
9578         if (caller == null) {
9579             String msg = "null IApplicationThread when getting content provider "
9580                     + name;
9581             Slog.w(TAG, msg);
9582             throw new SecurityException(msg);
9583         }
9584         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9585         // with cross-user grant.
9586         return getContentProviderImpl(caller, name, null, stable, userId);
9587     }
9588
9589     public ContentProviderHolder getContentProviderExternal(
9590             String name, int userId, IBinder token) {
9591         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9592             "Do not have permission in call getContentProviderExternal()");
9593         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9594                 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9595         return getContentProviderExternalUnchecked(name, token, userId);
9596     }
9597
9598     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9599             IBinder token, int userId) {
9600         return getContentProviderImpl(null, name, token, true, userId);
9601     }
9602
9603     /**
9604      * Drop a content provider from a ProcessRecord's bookkeeping
9605      */
9606     public void removeContentProvider(IBinder connection, boolean stable) {
9607         enforceNotIsolatedCaller("removeContentProvider");
9608         long ident = Binder.clearCallingIdentity();
9609         try {
9610             synchronized (this) {
9611                 ContentProviderConnection conn;
9612                 try {
9613                     conn = (ContentProviderConnection)connection;
9614                 } catch (ClassCastException e) {
9615                     String msg ="removeContentProvider: " + connection
9616                             + " not a ContentProviderConnection";
9617                     Slog.w(TAG, msg);
9618                     throw new IllegalArgumentException(msg);
9619                 }
9620                 if (conn == null) {
9621                     throw new NullPointerException("connection is null");
9622                 }
9623                 if (decProviderCountLocked(conn, null, null, stable)) {
9624                     updateOomAdjLocked();
9625                 }
9626             }
9627         } finally {
9628             Binder.restoreCallingIdentity(ident);
9629         }
9630     }
9631
9632     public void removeContentProviderExternal(String name, IBinder token) {
9633         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9634             "Do not have permission in call removeContentProviderExternal()");
9635         int userId = UserHandle.getCallingUserId();
9636         long ident = Binder.clearCallingIdentity();
9637         try {
9638             removeContentProviderExternalUnchecked(name, token, userId);
9639         } finally {
9640             Binder.restoreCallingIdentity(ident);
9641         }
9642     }
9643
9644     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9645         synchronized (this) {
9646             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9647             if(cpr == null) {
9648                 //remove from mProvidersByClass
9649                 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9650                 return;
9651             }
9652
9653             //update content provider record entry info
9654             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9655             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9656             if (localCpr.hasExternalProcessHandles()) {
9657                 if (localCpr.removeExternalProcessHandleLocked(token)) {
9658                     updateOomAdjLocked();
9659                 } else {
9660                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9661                             + " with no external reference for token: "
9662                             + token + ".");
9663                 }
9664             } else {
9665                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9666                         + " with no external references.");
9667             }
9668         }
9669     }
9670     
9671     public final void publishContentProviders(IApplicationThread caller,
9672             List<ContentProviderHolder> providers) {
9673         if (providers == null) {
9674             return;
9675         }
9676
9677         enforceNotIsolatedCaller("publishContentProviders");
9678         synchronized (this) {
9679             final ProcessRecord r = getRecordForAppLocked(caller);
9680             if (DEBUG_MU)
9681                 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9682             if (r == null) {
9683                 throw new SecurityException(
9684                         "Unable to find app for caller " + caller
9685                       + " (pid=" + Binder.getCallingPid()
9686                       + ") when publishing content providers");
9687             }
9688
9689             final long origId = Binder.clearCallingIdentity();
9690
9691             final int N = providers.size();
9692             for (int i=0; i<N; i++) {
9693                 ContentProviderHolder src = providers.get(i);
9694                 if (src == null || src.info == null || src.provider == null) {
9695                     continue;
9696                 }
9697                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9698                 if (DEBUG_MU)
9699                     Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9700                 if (dst != null) {
9701                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9702                     mProviderMap.putProviderByClass(comp, dst);
9703                     String names[] = dst.info.authority.split(";");
9704                     for (int j = 0; j < names.length; j++) {
9705                         mProviderMap.putProviderByName(names[j], dst);
9706                     }
9707
9708                     int NL = mLaunchingProviders.size();
9709                     int j;
9710                     for (j=0; j<NL; j++) {
9711                         if (mLaunchingProviders.get(j) == dst) {
9712                             mLaunchingProviders.remove(j);
9713                             j--;
9714                             NL--;
9715                         }
9716                     }
9717                     synchronized (dst) {
9718                         dst.provider = src.provider;
9719                         dst.proc = r;
9720                         dst.notifyAll();
9721                     }
9722                     updateOomAdjLocked(r);
9723                 }
9724             }
9725
9726             Binder.restoreCallingIdentity(origId);
9727         }
9728     }
9729
9730     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9731         ContentProviderConnection conn;
9732         try {
9733             conn = (ContentProviderConnection)connection;
9734         } catch (ClassCastException e) {
9735             String msg ="refContentProvider: " + connection
9736                     + " not a ContentProviderConnection";
9737             Slog.w(TAG, msg);
9738             throw new IllegalArgumentException(msg);
9739         }
9740         if (conn == null) {
9741             throw new NullPointerException("connection is null");
9742         }
9743
9744         synchronized (this) {
9745             if (stable > 0) {
9746                 conn.numStableIncs += stable;
9747             }
9748             stable = conn.stableCount + stable;
9749             if (stable < 0) {
9750                 throw new IllegalStateException("stableCount < 0: " + stable);
9751             }
9752
9753             if (unstable > 0) {
9754                 conn.numUnstableIncs += unstable;
9755             }
9756             unstable = conn.unstableCount + unstable;
9757             if (unstable < 0) {
9758                 throw new IllegalStateException("unstableCount < 0: " + unstable);
9759             }
9760
9761             if ((stable+unstable) <= 0) {
9762                 throw new IllegalStateException("ref counts can't go to zero here: stable="
9763                         + stable + " unstable=" + unstable);
9764             }
9765             conn.stableCount = stable;
9766             conn.unstableCount = unstable;
9767             return !conn.dead;
9768         }
9769     }
9770
9771     public void unstableProviderDied(IBinder connection) {
9772         ContentProviderConnection conn;
9773         try {
9774             conn = (ContentProviderConnection)connection;
9775         } catch (ClassCastException e) {
9776             String msg ="refContentProvider: " + connection
9777                     + " not a ContentProviderConnection";
9778             Slog.w(TAG, msg);
9779             throw new IllegalArgumentException(msg);
9780         }
9781         if (conn == null) {
9782             throw new NullPointerException("connection is null");
9783         }
9784
9785         // Safely retrieve the content provider associated with the connection.
9786         IContentProvider provider;
9787         synchronized (this) {
9788             provider = conn.provider.provider;
9789         }
9790
9791         if (provider == null) {
9792             // Um, yeah, we're way ahead of you.
9793             return;
9794         }
9795
9796         // Make sure the caller is being honest with us.
9797         if (provider.asBinder().pingBinder()) {
9798             // Er, no, still looks good to us.
9799             synchronized (this) {
9800                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9801                         + " says " + conn + " died, but we don't agree");
9802                 return;
9803             }
9804         }
9805
9806         // Well look at that!  It's dead!
9807         synchronized (this) {
9808             if (conn.provider.provider != provider) {
9809                 // But something changed...  good enough.
9810                 return;
9811             }
9812
9813             ProcessRecord proc = conn.provider.proc;
9814             if (proc == null || proc.thread == null) {
9815                 // Seems like the process is already cleaned up.
9816                 return;
9817             }
9818
9819             // As far as we're concerned, this is just like receiving a
9820             // death notification...  just a bit prematurely.
9821             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9822                     + ") early provider death");
9823             final long ident = Binder.clearCallingIdentity();
9824             try {
9825                 appDiedLocked(proc);
9826             } finally {
9827                 Binder.restoreCallingIdentity(ident);
9828             }
9829         }
9830     }
9831
9832     @Override
9833     public void appNotRespondingViaProvider(IBinder connection) {
9834         enforceCallingPermission(
9835                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9836
9837         final ContentProviderConnection conn = (ContentProviderConnection) connection;
9838         if (conn == null) {
9839             Slog.w(TAG, "ContentProviderConnection is null");
9840             return;
9841         }
9842
9843         final ProcessRecord host = conn.provider.proc;
9844         if (host == null) {
9845             Slog.w(TAG, "Failed to find hosting ProcessRecord");
9846             return;
9847         }
9848
9849         final long token = Binder.clearCallingIdentity();
9850         try {
9851             appNotResponding(host, null, null, false, "ContentProvider not responding");
9852         } finally {
9853             Binder.restoreCallingIdentity(token);
9854         }
9855     }
9856
9857     public final void installSystemProviders() {
9858         List<ProviderInfo> providers;
9859         synchronized (this) {
9860             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9861             providers = generateApplicationProvidersLocked(app);
9862             if (providers != null) {
9863                 for (int i=providers.size()-1; i>=0; i--) {
9864                     ProviderInfo pi = (ProviderInfo)providers.get(i);
9865                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9866                         Slog.w(TAG, "Not installing system proc provider " + pi.name
9867                                 + ": not system .apk");
9868                         providers.remove(i);
9869                     }
9870                 }
9871             }
9872         }
9873         if (providers != null) {
9874             mSystemThread.installSystemProviders(providers);
9875         }
9876
9877         mCoreSettingsObserver = new CoreSettingsObserver(this);
9878
9879         //mUsageStatsService.monitorPackages();
9880     }
9881
9882     /**
9883      * Allows apps to retrieve the MIME type of a URI.
9884      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9885      * users, then it does not need permission to access the ContentProvider.
9886      * Either, it needs cross-user uri grants.
9887      *
9888      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9889      *
9890      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9891      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9892      */
9893     public String getProviderMimeType(Uri uri, int userId) {
9894         enforceNotIsolatedCaller("getProviderMimeType");
9895         final String name = uri.getAuthority();
9896         int callingUid = Binder.getCallingUid();
9897         int callingPid = Binder.getCallingPid();
9898         long ident = 0;
9899         boolean clearedIdentity = false;
9900         userId = unsafeConvertIncomingUser(userId);
9901         if (canClearIdentity(callingPid, callingUid, userId)) {
9902             clearedIdentity = true;
9903             ident = Binder.clearCallingIdentity();
9904         }
9905         ContentProviderHolder holder = null;
9906         try {
9907             holder = getContentProviderExternalUnchecked(name, null, userId);
9908             if (holder != null) {
9909                 return holder.provider.getType(uri);
9910             }
9911         } catch (RemoteException e) {
9912             Log.w(TAG, "Content provider dead retrieving " + uri, e);
9913             return null;
9914         } finally {
9915             // We need to clear the identity to call removeContentProviderExternalUnchecked
9916             if (!clearedIdentity) {
9917                 ident = Binder.clearCallingIdentity();
9918             }
9919             try {
9920                 if (holder != null) {
9921                     removeContentProviderExternalUnchecked(name, null, userId);
9922                 }
9923             } finally {
9924                 Binder.restoreCallingIdentity(ident);
9925             }
9926         }
9927
9928         return null;
9929     }
9930
9931     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9932         if (UserHandle.getUserId(callingUid) == userId) {
9933             return true;
9934         }
9935         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9936                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9937                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9938                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9939                 return true;
9940         }
9941         return false;
9942     }
9943
9944     // =========================================================
9945     // GLOBAL MANAGEMENT
9946     // =========================================================
9947
9948     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9949             boolean isolated, int isolatedUid) {
9950         String proc = customProcess != null ? customProcess : info.processName;
9951         BatteryStatsImpl.Uid.Proc ps = null;
9952         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9953         final int userId = UserHandle.getUserId(info.uid);
9954         int uid = info.uid;
9955         if (isolated) {
9956             if (isolatedUid == 0) {
9957                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9958                 while (true) {
9959                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9960                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9961                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9962                     }
9963                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9964                     mNextIsolatedProcessUid++;
9965                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9966                         // No process for this uid, use it.
9967                         break;
9968                     }
9969                     stepsLeft--;
9970                     if (stepsLeft <= 0) {
9971                         return null;
9972                     }
9973                 }
9974             } else {
9975                 // Special case for startIsolatedProcess (internal only), where
9976                 // the uid of the isolated process is specified by the caller.
9977                 uid = isolatedUid;
9978             }
9979         }
9980         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
9981         if (!mBooted && !mBooting
9982                 && userId == UserHandle.USER_OWNER
9983                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
9984             r.persistent = true;
9985         }
9986         return r;
9987     }
9988
9989     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9990             String abiOverride) {
9991         ProcessRecord app;
9992         if (!isolated) {
9993             app = getProcessRecordLocked(info.processName, info.uid, true);
9994         } else {
9995             app = null;
9996         }
9997
9998         if (app == null) {
9999             app = newProcessRecordLocked(info, null, isolated, 0);
10000             mProcessNames.put(info.processName, app.uid, app);
10001             if (isolated) {
10002                 mIsolatedProcesses.put(app.uid, app);
10003             }
10004             updateLruProcessLocked(app, false, null);
10005             updateOomAdjLocked();
10006         }
10007
10008         // This package really, really can not be stopped.
10009         try {
10010             AppGlobals.getPackageManager().setPackageStoppedState(
10011                     info.packageName, false, UserHandle.getUserId(app.uid));
10012         } catch (RemoteException e) {
10013         } catch (IllegalArgumentException e) {
10014             Slog.w(TAG, "Failed trying to unstop package "
10015                     + info.packageName + ": " + e);
10016         }
10017
10018         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10019             app.persistent = true;
10020             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10021         }
10022         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10023             mPersistentStartingProcesses.add(app);
10024             startProcessLocked(app, "added application", app.processName, abiOverride,
10025                     null /* entryPoint */, null /* entryPointArgs */);
10026         }
10027
10028         return app;
10029     }
10030
10031     public void unhandledBack() {
10032         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10033                 "unhandledBack()");
10034
10035         synchronized(this) {
10036             final long origId = Binder.clearCallingIdentity();
10037             try {
10038                 getFocusedStack().unhandledBackLocked();
10039             } finally {
10040                 Binder.restoreCallingIdentity(origId);
10041             }
10042         }
10043     }
10044
10045     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10046         enforceNotIsolatedCaller("openContentUri");
10047         final int userId = UserHandle.getCallingUserId();
10048         String name = uri.getAuthority();
10049         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10050         ParcelFileDescriptor pfd = null;
10051         if (cph != null) {
10052             // We record the binder invoker's uid in thread-local storage before
10053             // going to the content provider to open the file.  Later, in the code
10054             // that handles all permissions checks, we look for this uid and use
10055             // that rather than the Activity Manager's own uid.  The effect is that
10056             // we do the check against the caller's permissions even though it looks
10057             // to the content provider like the Activity Manager itself is making
10058             // the request.
10059             Binder token = new Binder();
10060             sCallerIdentity.set(new Identity(
10061                     token, Binder.getCallingPid(), Binder.getCallingUid()));
10062             try {
10063                 pfd = cph.provider.openFile(null, uri, "r", null, token);
10064             } catch (FileNotFoundException e) {
10065                 // do nothing; pfd will be returned null
10066             } finally {
10067                 // Ensure that whatever happens, we clean up the identity state
10068                 sCallerIdentity.remove();
10069             }
10070
10071             // We've got the fd now, so we're done with the provider.
10072             removeContentProviderExternalUnchecked(name, null, userId);
10073         } else {
10074             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10075         }
10076         return pfd;
10077     }
10078
10079     // Actually is sleeping or shutting down or whatever else in the future
10080     // is an inactive state.
10081     public boolean isSleepingOrShuttingDown() {
10082         return isSleeping() || mShuttingDown;
10083     }
10084
10085     public boolean isSleeping() {
10086         return mSleeping;
10087     }
10088
10089     void onWakefulnessChanged(int wakefulness) {
10090         synchronized(this) {
10091             mWakefulness = wakefulness;
10092             updateSleepIfNeededLocked();
10093         }
10094     }
10095
10096     void finishRunningVoiceLocked() {
10097         if (mRunningVoice) {
10098             mRunningVoice = false;
10099             updateSleepIfNeededLocked();
10100         }
10101     }
10102
10103     void updateSleepIfNeededLocked() {
10104         if (mSleeping && !shouldSleepLocked()) {
10105             mSleeping = false;
10106             mStackSupervisor.comeOutOfSleepIfNeededLocked();
10107         } else if (!mSleeping && shouldSleepLocked()) {
10108             mSleeping = true;
10109             mStackSupervisor.goingToSleepLocked();
10110
10111             // Initialize the wake times of all processes.
10112             checkExcessivePowerUsageLocked(false);
10113             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10114             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10115             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10116         }
10117     }
10118
10119     private boolean shouldSleepLocked() {
10120         // Resume applications while running a voice interactor.
10121         if (mRunningVoice) {
10122             return false;
10123         }
10124
10125         switch (mWakefulness) {
10126             case PowerManagerInternal.WAKEFULNESS_AWAKE:
10127             case PowerManagerInternal.WAKEFULNESS_DREAMING:
10128                 // If we're interactive but applications are already paused then defer
10129                 // resuming them until the lock screen is hidden.
10130                 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10131             case PowerManagerInternal.WAKEFULNESS_DOZING:
10132                 // If we're dozing then pause applications whenever the lock screen is shown.
10133                 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10134             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10135             default:
10136                 // If we're asleep then pause applications unconditionally.
10137                 return true;
10138         }
10139     }
10140
10141     /** Pokes the task persister. */
10142     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10143         if (task != null && task.stack != null && task.stack.isHomeStack()) {
10144             // Never persist the home stack.
10145             return;
10146         }
10147         mTaskPersister.wakeup(task, flush);
10148     }
10149
10150     /** Notifies all listeners when the task stack has changed. */
10151     void notifyTaskStackChangedLocked() {
10152         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10153         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10154         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10155     }
10156
10157     @Override
10158     public boolean shutdown(int timeout) {
10159         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10160                 != PackageManager.PERMISSION_GRANTED) {
10161             throw new SecurityException("Requires permission "
10162                     + android.Manifest.permission.SHUTDOWN);
10163         }
10164
10165         boolean timedout = false;
10166
10167         synchronized(this) {
10168             mShuttingDown = true;
10169             updateEventDispatchingLocked();
10170             timedout = mStackSupervisor.shutdownLocked(timeout);
10171         }
10172
10173         mAppOpsService.shutdown();
10174         if (mUsageStatsService != null) {
10175             mUsageStatsService.prepareShutdown();
10176         }
10177         mBatteryStatsService.shutdown();
10178         synchronized (this) {
10179             mProcessStats.shutdownLocked();
10180             notifyTaskPersisterLocked(null, true);
10181         }
10182
10183         return timedout;
10184     }
10185
10186     public final void activitySlept(IBinder token) {
10187         if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10188
10189         final long origId = Binder.clearCallingIdentity();
10190
10191         synchronized (this) {
10192             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10193             if (r != null) {
10194                 mStackSupervisor.activitySleptLocked(r);
10195             }
10196         }
10197
10198         Binder.restoreCallingIdentity(origId);
10199     }
10200
10201     private String lockScreenShownToString() {
10202         switch (mLockScreenShown) {
10203             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10204             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10205             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10206             default: return "Unknown=" + mLockScreenShown;
10207         }
10208     }
10209
10210     void logLockScreen(String msg) {
10211         if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10212                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10213                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10214                 + " mSleeping=" + mSleeping);
10215     }
10216
10217     void startRunningVoiceLocked() {
10218         if (!mRunningVoice) {
10219             mRunningVoice = true;
10220             updateSleepIfNeededLocked();
10221         }
10222     }
10223
10224     private void updateEventDispatchingLocked() {
10225         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10226     }
10227
10228     public void setLockScreenShown(boolean shown) {
10229         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10230                 != PackageManager.PERMISSION_GRANTED) {
10231             throw new SecurityException("Requires permission "
10232                     + android.Manifest.permission.DEVICE_POWER);
10233         }
10234
10235         synchronized(this) {
10236             long ident = Binder.clearCallingIdentity();
10237             try {
10238                 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10239                 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10240                 updateSleepIfNeededLocked();
10241             } finally {
10242                 Binder.restoreCallingIdentity(ident);
10243             }
10244         }
10245     }
10246
10247     @Override
10248     public void stopAppSwitches() {
10249         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10250                 != PackageManager.PERMISSION_GRANTED) {
10251             throw new SecurityException("Requires permission "
10252                     + android.Manifest.permission.STOP_APP_SWITCHES);
10253         }
10254         
10255         synchronized(this) {
10256             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10257                     + APP_SWITCH_DELAY_TIME;
10258             mDidAppSwitch = false;
10259             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10260             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10261             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10262         }
10263     }
10264     
10265     public void resumeAppSwitches() {
10266         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10267                 != PackageManager.PERMISSION_GRANTED) {
10268             throw new SecurityException("Requires permission "
10269                     + android.Manifest.permission.STOP_APP_SWITCHES);
10270         }
10271         
10272         synchronized(this) {
10273             // Note that we don't execute any pending app switches... we will
10274             // let those wait until either the timeout, or the next start
10275             // activity request.
10276             mAppSwitchesAllowedTime = 0;
10277         }
10278     }
10279     
10280     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10281             int callingPid, int callingUid, String name) {
10282         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10283             return true;
10284         }
10285
10286         int perm = checkComponentPermission(
10287                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10288                 sourceUid, -1, true);
10289         if (perm == PackageManager.PERMISSION_GRANTED) {
10290             return true;
10291         }
10292
10293         // If the actual IPC caller is different from the logical source, then
10294         // also see if they are allowed to control app switches.
10295         if (callingUid != -1 && callingUid != sourceUid) {
10296             perm = checkComponentPermission(
10297                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10298                     callingUid, -1, true);
10299             if (perm == PackageManager.PERMISSION_GRANTED) {
10300                 return true;
10301             }
10302         }
10303
10304         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10305         return false;
10306     }
10307     
10308     public void setDebugApp(String packageName, boolean waitForDebugger,
10309             boolean persistent) {
10310         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10311                 "setDebugApp()");
10312
10313         long ident = Binder.clearCallingIdentity();
10314         try {
10315             // Note that this is not really thread safe if there are multiple
10316             // callers into it at the same time, but that's not a situation we
10317             // care about.
10318             if (persistent) {
10319                 final ContentResolver resolver = mContext.getContentResolver();
10320                 Settings.Global.putString(
10321                     resolver, Settings.Global.DEBUG_APP,
10322                     packageName);
10323                 Settings.Global.putInt(
10324                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10325                     waitForDebugger ? 1 : 0);
10326             }
10327
10328             synchronized (this) {
10329                 if (!persistent) {
10330                     mOrigDebugApp = mDebugApp;
10331                     mOrigWaitForDebugger = mWaitForDebugger;
10332                 }
10333                 mDebugApp = packageName;
10334                 mWaitForDebugger = waitForDebugger;
10335                 mDebugTransient = !persistent;
10336                 if (packageName != null) {
10337                     forceStopPackageLocked(packageName, -1, false, false, true, true,
10338                             false, UserHandle.USER_ALL, "set debug app");
10339                 }
10340             }
10341         } finally {
10342             Binder.restoreCallingIdentity(ident);
10343         }
10344     }
10345
10346     void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10347         synchronized (this) {
10348             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10349             if (!isDebuggable) {
10350                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10351                     throw new SecurityException("Process not debuggable: " + app.packageName);
10352                 }
10353             }
10354
10355             mOpenGlTraceApp = processName;
10356         }
10357     }
10358
10359     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10360         synchronized (this) {
10361             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10362             if (!isDebuggable) {
10363                 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10364                     throw new SecurityException("Process not debuggable: " + app.packageName);
10365                 }
10366             }
10367             mProfileApp = processName;
10368             mProfileFile = profilerInfo.profileFile;
10369             if (mProfileFd != null) {
10370                 try {
10371                     mProfileFd.close();
10372                 } catch (IOException e) {
10373                 }
10374                 mProfileFd = null;
10375             }
10376             mProfileFd = profilerInfo.profileFd;
10377             mSamplingInterval = profilerInfo.samplingInterval;
10378             mAutoStopProfiler = profilerInfo.autoStopProfiler;
10379             mProfileType = 0;
10380         }
10381     }
10382
10383     @Override
10384     public void setAlwaysFinish(boolean enabled) {
10385         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10386                 "setAlwaysFinish()");
10387
10388         Settings.Global.putInt(
10389                 mContext.getContentResolver(),
10390                 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10391
10392         synchronized (this) {
10393             mAlwaysFinishActivities = enabled;
10394         }
10395     }
10396
10397     @Override
10398     public void setActivityController(IActivityController controller) {
10399         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10400                 "setActivityController()");
10401         synchronized (this) {
10402             mController = controller;
10403             Watchdog.getInstance().setActivityController(controller);
10404         }
10405     }
10406
10407     @Override
10408     public void setUserIsMonkey(boolean userIsMonkey) {
10409         synchronized (this) {
10410             synchronized (mPidsSelfLocked) {
10411                 final int callingPid = Binder.getCallingPid();
10412                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10413                 if (precessRecord == null) {
10414                     throw new SecurityException("Unknown process: " + callingPid);
10415                 }
10416                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
10417                     throw new SecurityException("Only an instrumentation process "
10418                             + "with a UiAutomation can call setUserIsMonkey");
10419                 }
10420             }
10421             mUserIsMonkey = userIsMonkey;
10422         }
10423     }
10424
10425     @Override
10426     public boolean isUserAMonkey() {
10427         synchronized (this) {
10428             // If there is a controller also implies the user is a monkey.
10429             return (mUserIsMonkey || mController != null);
10430         }
10431     }
10432
10433     public void requestBugReport() {
10434         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10435         SystemProperties.set("ctl.start", "bugreport");
10436     }
10437
10438     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10439         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10440     }
10441
10442     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10443         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10444             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10445         }
10446         return KEY_DISPATCHING_TIMEOUT;
10447     }
10448
10449     @Override
10450     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10451         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10452                 != PackageManager.PERMISSION_GRANTED) {
10453             throw new SecurityException("Requires permission "
10454                     + android.Manifest.permission.FILTER_EVENTS);
10455         }
10456         ProcessRecord proc;
10457         long timeout;
10458         synchronized (this) {
10459             synchronized (mPidsSelfLocked) {
10460                 proc = mPidsSelfLocked.get(pid);
10461             }
10462             timeout = getInputDispatchingTimeoutLocked(proc);
10463         }
10464
10465         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10466             return -1;
10467         }
10468
10469         return timeout;
10470     }
10471
10472     /**
10473      * Handle input dispatching timeouts.
10474      * Returns whether input dispatching should be aborted or not.
10475      */
10476     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10477             final ActivityRecord activity, final ActivityRecord parent,
10478             final boolean aboveSystem, String reason) {
10479         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10480                 != PackageManager.PERMISSION_GRANTED) {
10481             throw new SecurityException("Requires permission "
10482                     + android.Manifest.permission.FILTER_EVENTS);
10483         }
10484
10485         final String annotation;
10486         if (reason == null) {
10487             annotation = "Input dispatching timed out";
10488         } else {
10489             annotation = "Input dispatching timed out (" + reason + ")";
10490         }
10491
10492         if (proc != null) {
10493             synchronized (this) {
10494                 if (proc.debugging) {
10495                     return false;
10496                 }
10497
10498                 if (mDidDexOpt) {
10499                     // Give more time since we were dexopting.
10500                     mDidDexOpt = false;
10501                     return false;
10502                 }
10503
10504                 if (proc.instrumentationClass != null) {
10505                     Bundle info = new Bundle();
10506                     info.putString("shortMsg", "keyDispatchingTimedOut");
10507                     info.putString("longMsg", annotation);
10508                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10509                     return true;
10510                 }
10511             }
10512             mHandler.post(new Runnable() {
10513                 @Override
10514                 public void run() {
10515                     appNotResponding(proc, activity, parent, aboveSystem, annotation);
10516                 }
10517             });
10518         }
10519
10520         return true;
10521     }
10522
10523     public Bundle getAssistContextExtras(int requestType) {
10524         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10525                 UserHandle.getCallingUserId());
10526         if (pae == null) {
10527             return null;
10528         }
10529         synchronized (pae) {
10530             while (!pae.haveResult) {
10531                 try {
10532                     pae.wait();
10533                 } catch (InterruptedException e) {
10534                 }
10535             }
10536             if (pae.result != null) {
10537                 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10538             }
10539         }
10540         synchronized (this) {
10541             mPendingAssistExtras.remove(pae);
10542             mHandler.removeCallbacks(pae);
10543         }
10544         return pae.extras;
10545     }
10546
10547     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10548             int userHandle) {
10549         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10550                 "getAssistContextExtras()");
10551         PendingAssistExtras pae;
10552         Bundle extras = new Bundle();
10553         synchronized (this) {
10554             ActivityRecord activity = getFocusedStack().mResumedActivity;
10555             if (activity == null) {
10556                 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10557                 return null;
10558             }
10559             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10560             if (activity.app == null || activity.app.thread == null) {
10561                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10562                 return null;
10563             }
10564             if (activity.app.pid == Binder.getCallingPid()) {
10565                 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10566                 return null;
10567             }
10568             pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10569             try {
10570                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10571                         requestType);
10572                 mPendingAssistExtras.add(pae);
10573                 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10574             } catch (RemoteException e) {
10575                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10576                 return null;
10577             }
10578             return pae;
10579         }
10580     }
10581
10582     public void reportAssistContextExtras(IBinder token, Bundle extras) {
10583         PendingAssistExtras pae = (PendingAssistExtras)token;
10584         synchronized (pae) {
10585             pae.result = extras;
10586             pae.haveResult = true;
10587             pae.notifyAll();
10588             if (pae.intent == null) {
10589                 // Caller is just waiting for the result.
10590                 return;
10591             }
10592         }
10593
10594         // We are now ready to launch the assist activity.
10595         synchronized (this) {
10596             boolean exists = mPendingAssistExtras.remove(pae);
10597             mHandler.removeCallbacks(pae);
10598             if (!exists) {
10599                 // Timed out.
10600                 return;
10601             }
10602         }
10603         pae.intent.replaceExtras(extras);
10604         if (pae.hint != null) {
10605             pae.intent.putExtra(pae.hint, true);
10606         }
10607         pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10608                 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10609                 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10610         closeSystemDialogs("assist");
10611         try {
10612             mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10613         } catch (ActivityNotFoundException e) {
10614             Slog.w(TAG, "No activity to handle assist action.", e);
10615         }
10616     }
10617
10618     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10619         return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10620     }
10621
10622     public void registerProcessObserver(IProcessObserver observer) {
10623         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10624                 "registerProcessObserver()");
10625         synchronized (this) {
10626             mProcessObservers.register(observer);
10627         }
10628     }
10629
10630     @Override
10631     public void unregisterProcessObserver(IProcessObserver observer) {
10632         synchronized (this) {
10633             mProcessObservers.unregister(observer);
10634         }
10635     }
10636
10637     @Override
10638     public boolean convertFromTranslucent(IBinder token) {
10639         final long origId = Binder.clearCallingIdentity();
10640         try {
10641             synchronized (this) {
10642                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10643                 if (r == null) {
10644                     return false;
10645                 }
10646                 final boolean translucentChanged = r.changeWindowTranslucency(true);
10647                 if (translucentChanged) {
10648                     r.task.stack.releaseBackgroundResources();
10649                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10650                 }
10651                 mWindowManager.setAppFullscreen(token, true);
10652                 return translucentChanged;
10653             }
10654         } finally {
10655             Binder.restoreCallingIdentity(origId);
10656         }
10657     }
10658
10659     @Override
10660     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10661         final long origId = Binder.clearCallingIdentity();
10662         try {
10663             synchronized (this) {
10664                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10665                 if (r == null) {
10666                     return false;
10667                 }
10668                 int index = r.task.mActivities.lastIndexOf(r);
10669                 if (index > 0) {
10670                     ActivityRecord under = r.task.mActivities.get(index - 1);
10671                     under.returningOptions = options;
10672                 }
10673                 final boolean translucentChanged = r.changeWindowTranslucency(false);
10674                 if (translucentChanged) {
10675                     r.task.stack.convertToTranslucent(r);
10676                 }
10677                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10678                 mWindowManager.setAppFullscreen(token, false);
10679                 return translucentChanged;
10680             }
10681         } finally {
10682             Binder.restoreCallingIdentity(origId);
10683         }
10684     }
10685
10686     @Override
10687     public boolean requestVisibleBehind(IBinder token, boolean visible) {
10688         final long origId = Binder.clearCallingIdentity();
10689         try {
10690             synchronized (this) {
10691                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10692                 if (r != null) {
10693                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10694                 }
10695             }
10696             return false;
10697         } finally {
10698             Binder.restoreCallingIdentity(origId);
10699         }
10700     }
10701
10702     @Override
10703     public boolean isBackgroundVisibleBehind(IBinder token) {
10704         final long origId = Binder.clearCallingIdentity();
10705         try {
10706             synchronized (this) {
10707                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10708                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10709                 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10710                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10711                 return visible;
10712             }
10713         } finally {
10714             Binder.restoreCallingIdentity(origId);
10715         }
10716     }
10717
10718     @Override
10719     public ActivityOptions getActivityOptions(IBinder token) {
10720         final long origId = Binder.clearCallingIdentity();
10721         try {
10722             synchronized (this) {
10723                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10724                 if (r != null) {
10725                     final ActivityOptions activityOptions = r.pendingOptions;
10726                     r.pendingOptions = null;
10727                     return activityOptions;
10728                 }
10729                 return null;
10730             }
10731         } finally {
10732             Binder.restoreCallingIdentity(origId);
10733         }
10734     }
10735
10736     @Override
10737     public void setImmersive(IBinder token, boolean immersive) {
10738         synchronized(this) {
10739             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10740             if (r == null) {
10741                 throw new IllegalArgumentException();
10742             }
10743             r.immersive = immersive;
10744
10745             // update associated state if we're frontmost
10746             if (r == mFocusedActivity) {
10747                 if (DEBUG_IMMERSIVE) {
10748                     Slog.d(TAG, "Frontmost changed immersion: "+ r);
10749                 }
10750                 applyUpdateLockStateLocked(r);
10751             }
10752         }
10753     }
10754
10755     @Override
10756     public boolean isImmersive(IBinder token) {
10757         synchronized (this) {
10758             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10759             if (r == null) {
10760                 throw new IllegalArgumentException();
10761             }
10762             return r.immersive;
10763         }
10764     }
10765
10766     public boolean isTopActivityImmersive() {
10767         enforceNotIsolatedCaller("startActivity");
10768         synchronized (this) {
10769             ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10770             return (r != null) ? r.immersive : false;
10771         }
10772     }
10773
10774     @Override
10775     public boolean isTopOfTask(IBinder token) {
10776         synchronized (this) {
10777             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10778             if (r == null) {
10779                 throw new IllegalArgumentException();
10780             }
10781             return r.task.getTopActivity() == r;
10782         }
10783     }
10784
10785     public final void enterSafeMode() {
10786         synchronized(this) {
10787             // It only makes sense to do this before the system is ready
10788             // and started launching other packages.
10789             if (!mSystemReady) {
10790                 try {
10791                     AppGlobals.getPackageManager().enterSafeMode();
10792                 } catch (RemoteException e) {
10793                 }
10794             }
10795
10796             mSafeMode = true;
10797         }
10798     }
10799
10800     public final void showSafeModeOverlay() {
10801         View v = LayoutInflater.from(mContext).inflate(
10802                 com.android.internal.R.layout.safe_mode, null);
10803         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10804         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10805         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10806         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10807         lp.gravity = Gravity.BOTTOM | Gravity.START;
10808         lp.format = v.getBackground().getOpacity();
10809         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10810                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10811         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10812         ((WindowManager)mContext.getSystemService(
10813                 Context.WINDOW_SERVICE)).addView(v, lp);
10814     }
10815
10816     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10817         if (!(sender instanceof PendingIntentRecord)) {
10818             return;
10819         }
10820         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10821         synchronized (stats) {
10822             if (mBatteryStatsService.isOnBattery()) {
10823                 mBatteryStatsService.enforceCallingPermission();
10824                 PendingIntentRecord rec = (PendingIntentRecord)sender;
10825                 int MY_UID = Binder.getCallingUid();
10826                 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10827                 BatteryStatsImpl.Uid.Pkg pkg =
10828                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10829                             sourcePkg != null ? sourcePkg : rec.key.packageName);
10830                 pkg.incWakeupsLocked();
10831             }
10832         }
10833     }
10834
10835     public boolean killPids(int[] pids, String pReason, boolean secure) {
10836         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10837             throw new SecurityException("killPids only available to the system");
10838         }
10839         String reason = (pReason == null) ? "Unknown" : pReason;
10840         // XXX Note: don't acquire main activity lock here, because the window
10841         // manager calls in with its locks held.
10842
10843         boolean killed = false;
10844         synchronized (mPidsSelfLocked) {
10845             int[] types = new int[pids.length];
10846             int worstType = 0;
10847             for (int i=0; i<pids.length; i++) {
10848                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10849                 if (proc != null) {
10850                     int type = proc.setAdj;
10851                     types[i] = type;
10852                     if (type > worstType) {
10853                         worstType = type;
10854                     }
10855                 }
10856             }
10857
10858             // If the worst oom_adj is somewhere in the cached proc LRU range,
10859             // then constrain it so we will kill all cached procs.
10860             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10861                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10862                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10863             }
10864
10865             // If this is not a secure call, don't let it kill processes that
10866             // are important.
10867             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10868                 worstType = ProcessList.SERVICE_ADJ;
10869             }
10870
10871             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10872             for (int i=0; i<pids.length; i++) {
10873                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10874                 if (proc == null) {
10875                     continue;
10876                 }
10877                 int adj = proc.setAdj;
10878                 if (adj >= worstType && !proc.killedByAm) {
10879                     proc.kill(reason, true);
10880                     killed = true;
10881                 }
10882             }
10883         }
10884         return killed;
10885     }
10886
10887     @Override
10888     public void killUid(int uid, String reason) {
10889         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10890             throw new SecurityException("killUid only available to the system");
10891         }
10892         synchronized (this) {
10893             killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10894                     ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10895                     reason != null ? reason : "kill uid");
10896         }
10897     }
10898
10899     @Override
10900     public boolean killProcessesBelowForeground(String reason) {
10901         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10902             throw new SecurityException("killProcessesBelowForeground() only available to system");
10903         }
10904
10905         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10906     }
10907
10908     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10909         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10910             throw new SecurityException("killProcessesBelowAdj() only available to system");
10911         }
10912
10913         boolean killed = false;
10914         synchronized (mPidsSelfLocked) {
10915             final int size = mPidsSelfLocked.size();
10916             for (int i = 0; i < size; i++) {
10917                 final int pid = mPidsSelfLocked.keyAt(i);
10918                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10919                 if (proc == null) continue;
10920
10921                 final int adj = proc.setAdj;
10922                 if (adj > belowAdj && !proc.killedByAm) {
10923                     proc.kill(reason, true);
10924                     killed = true;
10925                 }
10926             }
10927         }
10928         return killed;
10929     }
10930
10931     @Override
10932     public void hang(final IBinder who, boolean allowRestart) {
10933         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10934                 != PackageManager.PERMISSION_GRANTED) {
10935             throw new SecurityException("Requires permission "
10936                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10937         }
10938
10939         final IBinder.DeathRecipient death = new DeathRecipient() {
10940             @Override
10941             public void binderDied() {
10942                 synchronized (this) {
10943                     notifyAll();
10944                 }
10945             }
10946         };
10947
10948         try {
10949             who.linkToDeath(death, 0);
10950         } catch (RemoteException e) {
10951             Slog.w(TAG, "hang: given caller IBinder is already dead.");
10952             return;
10953         }
10954
10955         synchronized (this) {
10956             Watchdog.getInstance().setAllowRestart(allowRestart);
10957             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10958             synchronized (death) {
10959                 while (who.isBinderAlive()) {
10960                     try {
10961                         death.wait();
10962                     } catch (InterruptedException e) {
10963                     }
10964                 }
10965             }
10966             Watchdog.getInstance().setAllowRestart(true);
10967         }
10968     }
10969
10970     @Override
10971     public void restart() {
10972         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10973                 != PackageManager.PERMISSION_GRANTED) {
10974             throw new SecurityException("Requires permission "
10975                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10976         }
10977
10978         Log.i(TAG, "Sending shutdown broadcast...");
10979
10980         BroadcastReceiver br = new BroadcastReceiver() {
10981             @Override public void onReceive(Context context, Intent intent) {
10982                 // Now the broadcast is done, finish up the low-level shutdown.
10983                 Log.i(TAG, "Shutting down activity manager...");
10984                 shutdown(10000);
10985                 Log.i(TAG, "Shutdown complete, restarting!");
10986                 Process.killProcess(Process.myPid());
10987                 System.exit(10);
10988             }
10989         };
10990
10991         // First send the high-level shut down broadcast.
10992         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10993         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10994         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10995         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10996         mContext.sendOrderedBroadcastAsUser(intent,
10997                 UserHandle.ALL, null, br, mHandler, 0, null, null);
10998         */
10999         br.onReceive(mContext, intent);
11000     }
11001
11002     private long getLowRamTimeSinceIdle(long now) {
11003         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11004     }
11005
11006     @Override
11007     public void performIdleMaintenance() {
11008         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11009                 != PackageManager.PERMISSION_GRANTED) {
11010             throw new SecurityException("Requires permission "
11011                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11012         }
11013
11014         synchronized (this) {
11015             final long now = SystemClock.uptimeMillis();
11016             final long timeSinceLastIdle = now - mLastIdleTime;
11017             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11018             mLastIdleTime = now;
11019             mLowRamTimeSinceLastIdle = 0;
11020             if (mLowRamStartTime != 0) {
11021                 mLowRamStartTime = now;
11022             }
11023
11024             StringBuilder sb = new StringBuilder(128);
11025             sb.append("Idle maintenance over ");
11026             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11027             sb.append(" low RAM for ");
11028             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11029             Slog.i(TAG, sb.toString());
11030
11031             // If at least 1/3 of our time since the last idle period has been spent
11032             // with RAM low, then we want to kill processes.
11033             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11034
11035             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11036                 ProcessRecord proc = mLruProcesses.get(i);
11037                 if (proc.notCachedSinceIdle) {
11038                     if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11039                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11040                         if (doKilling && proc.initialIdlePss != 0
11041                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11042                             sb = new StringBuilder(128);
11043                             sb.append("Kill");
11044                             sb.append(proc.processName);
11045                             sb.append(" in idle maint: pss=");
11046                             sb.append(proc.lastPss);
11047                             sb.append(", initialPss=");
11048                             sb.append(proc.initialIdlePss);
11049                             sb.append(", period=");
11050                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
11051                             sb.append(", lowRamPeriod=");
11052                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11053                             Slog.wtfQuiet(TAG, sb.toString());
11054                             proc.kill("idle maint (pss " + proc.lastPss
11055                                     + " from " + proc.initialIdlePss + ")", true);
11056                         }
11057                     }
11058                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11059                     proc.notCachedSinceIdle = true;
11060                     proc.initialIdlePss = 0;
11061                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11062                             mTestPssMode, isSleeping(), now);
11063                 }
11064             }
11065
11066             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11067             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11068         }
11069     }
11070
11071     private void retrieveSettings() {
11072         final ContentResolver resolver = mContext.getContentResolver();
11073         String debugApp = Settings.Global.getString(
11074             resolver, Settings.Global.DEBUG_APP);
11075         boolean waitForDebugger = Settings.Global.getInt(
11076             resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11077         boolean alwaysFinishActivities = Settings.Global.getInt(
11078             resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11079         boolean forceRtl = Settings.Global.getInt(
11080                 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11081         // Transfer any global setting for forcing RTL layout, into a System Property
11082         SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11083
11084         Configuration configuration = new Configuration();
11085         Settings.System.getConfiguration(resolver, configuration);
11086         if (forceRtl) {
11087             // This will take care of setting the correct layout direction flags
11088             configuration.setLayoutDirection(configuration.locale);
11089         }
11090
11091         synchronized (this) {
11092             mDebugApp = mOrigDebugApp = debugApp;
11093             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11094             mAlwaysFinishActivities = alwaysFinishActivities;
11095             // This happens before any activities are started, so we can
11096             // change mConfiguration in-place.
11097             updateConfigurationLocked(configuration, null, false, true);
11098             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11099         }
11100     }
11101
11102     /** Loads resources after the current configuration has been set. */
11103     private void loadResourcesOnSystemReady() {
11104         final Resources res = mContext.getResources();
11105         mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11106         mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11107         mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11108     }
11109
11110     public boolean testIsSystemReady() {
11111         // no need to synchronize(this) just to read & return the value
11112         return mSystemReady;
11113     }
11114
11115     private static File getCalledPreBootReceiversFile() {
11116         File dataDir = Environment.getDataDirectory();
11117         File systemDir = new File(dataDir, "system");
11118         File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11119         return fname;
11120     }
11121
11122     private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11123         ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11124         File file = getCalledPreBootReceiversFile();
11125         FileInputStream fis = null;
11126         try {
11127             fis = new FileInputStream(file);
11128             DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11129             int fvers = dis.readInt();
11130             if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11131                 String vers = dis.readUTF();
11132                 String codename = dis.readUTF();
11133                 String build = dis.readUTF();
11134                 if (android.os.Build.VERSION.RELEASE.equals(vers)
11135                         && android.os.Build.VERSION.CODENAME.equals(codename)
11136                         && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11137                     int num = dis.readInt();
11138                     while (num > 0) {
11139                         num--;
11140                         String pkg = dis.readUTF();
11141                         String cls = dis.readUTF();
11142                         lastDoneReceivers.add(new ComponentName(pkg, cls));
11143                     }
11144                 }
11145             }
11146         } catch (FileNotFoundException e) {
11147         } catch (IOException e) {
11148             Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11149         } finally {
11150             if (fis != null) {
11151                 try {
11152                     fis.close();
11153                 } catch (IOException e) {
11154                 }
11155             }
11156         }
11157         return lastDoneReceivers;
11158     }
11159
11160     private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11161         File file = getCalledPreBootReceiversFile();
11162         FileOutputStream fos = null;
11163         DataOutputStream dos = null;
11164         try {
11165             fos = new FileOutputStream(file);
11166             dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11167             dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11168             dos.writeUTF(android.os.Build.VERSION.RELEASE);
11169             dos.writeUTF(android.os.Build.VERSION.CODENAME);
11170             dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11171             dos.writeInt(list.size());
11172             for (int i=0; i<list.size(); i++) {
11173                 dos.writeUTF(list.get(i).getPackageName());
11174                 dos.writeUTF(list.get(i).getClassName());
11175             }
11176         } catch (IOException e) {
11177             Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11178             file.delete();
11179         } finally {
11180             FileUtils.sync(fos);
11181             if (dos != null) {
11182                 try {
11183                     dos.close();
11184                 } catch (IOException e) {
11185                     // TODO Auto-generated catch block
11186                     e.printStackTrace();
11187                 }
11188             }
11189         }
11190     }
11191
11192     private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11193             ArrayList<ComponentName> doneReceivers, int userId) {
11194         boolean waitingUpdate = false;
11195         Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11196         List<ResolveInfo> ris = null;
11197         try {
11198             ris = AppGlobals.getPackageManager().queryIntentReceivers(
11199                     intent, null, 0, userId);
11200         } catch (RemoteException e) {
11201         }
11202         if (ris != null) {
11203             for (int i=ris.size()-1; i>=0; i--) {
11204                 if ((ris.get(i).activityInfo.applicationInfo.flags
11205                         &ApplicationInfo.FLAG_SYSTEM) == 0) {
11206                     ris.remove(i);
11207                 }
11208             }
11209             intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11210
11211             // For User 0, load the version number. When delivering to a new user, deliver
11212             // to all receivers.
11213             if (userId == UserHandle.USER_OWNER) {
11214                 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11215                 for (int i=0; i<ris.size(); i++) {
11216                     ActivityInfo ai = ris.get(i).activityInfo;
11217                     ComponentName comp = new ComponentName(ai.packageName, ai.name);
11218                     if (lastDoneReceivers.contains(comp)) {
11219                         // We already did the pre boot receiver for this app with the current
11220                         // platform version, so don't do it again...
11221                         ris.remove(i);
11222                         i--;
11223                         // ...however, do keep it as one that has been done, so we don't
11224                         // forget about it when rewriting the file of last done receivers.
11225                         doneReceivers.add(comp);
11226                     }
11227                 }
11228             }
11229
11230             // If primary user, send broadcast to all available users, else just to userId
11231             final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11232                     : new int[] { userId };
11233             for (int i = 0; i < ris.size(); i++) {
11234                 ActivityInfo ai = ris.get(i).activityInfo;
11235                 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11236                 doneReceivers.add(comp);
11237                 intent.setComponent(comp);
11238                 for (int j=0; j<users.length; j++) {
11239                     IIntentReceiver finisher = null;
11240                     // On last receiver and user, set up a completion callback
11241                     if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11242                         finisher = new IIntentReceiver.Stub() {
11243                             public void performReceive(Intent intent, int resultCode,
11244                                     String data, Bundle extras, boolean ordered,
11245                                     boolean sticky, int sendingUser) {
11246                                 // The raw IIntentReceiver interface is called
11247                                 // with the AM lock held, so redispatch to
11248                                 // execute our code without the lock.
11249                                 mHandler.post(onFinishCallback);
11250                             }
11251                         };
11252                     }
11253                     Slog.i(TAG, "Sending system update to " + intent.getComponent()
11254                             + " for user " + users[j]);
11255                     broadcastIntentLocked(null, null, intent, null, finisher,
11256                             0, null, null, null, AppOpsManager.OP_NONE,
11257                             true, false, MY_PID, Process.SYSTEM_UID,
11258                             users[j]);
11259                     if (finisher != null) {
11260                         waitingUpdate = true;
11261                     }
11262                 }
11263             }
11264         }
11265
11266         return waitingUpdate;
11267     }
11268
11269     public void systemReady(final Runnable goingCallback) {
11270         synchronized(this) {
11271             if (mSystemReady) {
11272                 // If we're done calling all the receivers, run the next "boot phase" passed in
11273                 // by the SystemServer
11274                 if (goingCallback != null) {
11275                     goingCallback.run();
11276                 }
11277                 return;
11278             }
11279
11280             // Make sure we have the current profile info, since it is needed for
11281             // security checks.
11282             updateCurrentProfileIdsLocked();
11283
11284             if (mRecentTasks == null) {
11285                 mRecentTasks = mTaskPersister.restoreTasksLocked();
11286                 mTaskPersister.restoreTasksFromOtherDeviceLocked();
11287                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11288                 mTaskPersister.startPersisting();
11289             }
11290
11291             // Check to see if there are any update receivers to run.
11292             if (!mDidUpdate) {
11293                 if (mWaitingUpdate) {
11294                     return;
11295                 }
11296                 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11297                 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11298                     public void run() {
11299                         synchronized (ActivityManagerService.this) {
11300                             mDidUpdate = true;
11301                         }
11302                         writeLastDonePreBootReceivers(doneReceivers);
11303                         showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11304                                 false);
11305                         systemReady(goingCallback);
11306                     }
11307                 }, doneReceivers, UserHandle.USER_OWNER);
11308
11309                 if (mWaitingUpdate) {
11310                     return;
11311                 }
11312                 mDidUpdate = true;
11313             }
11314
11315             mAppOpsService.systemReady();
11316             mSystemReady = true;
11317         }
11318
11319         ArrayList<ProcessRecord> procsToKill = null;
11320         synchronized(mPidsSelfLocked) {
11321             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11322                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11323                 if (!isAllowedWhileBooting(proc.info)){
11324                     if (procsToKill == null) {
11325                         procsToKill = new ArrayList<ProcessRecord>();
11326                     }
11327                     procsToKill.add(proc);
11328                 }
11329             }
11330         }
11331         
11332         synchronized(this) {
11333             if (procsToKill != null) {
11334                 for (int i=procsToKill.size()-1; i>=0; i--) {
11335                     ProcessRecord proc = procsToKill.get(i);
11336                     Slog.i(TAG, "Removing system update proc: " + proc);
11337                     removeProcessLocked(proc, true, false, "system update done");
11338                 }
11339             }
11340             
11341             // Now that we have cleaned up any update processes, we
11342             // are ready to start launching real processes and know that
11343             // we won't trample on them any more.
11344             mProcessesReady = true;
11345         }
11346         
11347         Slog.i(TAG, "System now ready");
11348         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11349             SystemClock.uptimeMillis());
11350
11351         synchronized(this) {
11352             // Make sure we have no pre-ready processes sitting around.
11353             
11354             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11355                 ResolveInfo ri = mContext.getPackageManager()
11356                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11357                                 STOCK_PM_FLAGS);
11358                 CharSequence errorMsg = null;
11359                 if (ri != null) {
11360                     ActivityInfo ai = ri.activityInfo;
11361                     ApplicationInfo app = ai.applicationInfo;
11362                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11363                         mTopAction = Intent.ACTION_FACTORY_TEST;
11364                         mTopData = null;
11365                         mTopComponent = new ComponentName(app.packageName,
11366                                 ai.name);
11367                     } else {
11368                         errorMsg = mContext.getResources().getText(
11369                                 com.android.internal.R.string.factorytest_not_system);
11370                     }
11371                 } else {
11372                     errorMsg = mContext.getResources().getText(
11373                             com.android.internal.R.string.factorytest_no_action);
11374                 }
11375                 if (errorMsg != null) {
11376                     mTopAction = null;
11377                     mTopData = null;
11378                     mTopComponent = null;
11379                     Message msg = Message.obtain();
11380                     msg.what = SHOW_FACTORY_ERROR_MSG;
11381                     msg.getData().putCharSequence("msg", errorMsg);
11382                     mHandler.sendMessage(msg);
11383                 }
11384             }
11385         }
11386
11387         retrieveSettings();
11388         loadResourcesOnSystemReady();
11389
11390         synchronized (this) {
11391             readGrantedUriPermissionsLocked();
11392         }
11393
11394         if (goingCallback != null) goingCallback.run();
11395
11396         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11397                 Integer.toString(mCurrentUserId), mCurrentUserId);
11398         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11399                 Integer.toString(mCurrentUserId), mCurrentUserId);
11400         mSystemServiceManager.startUser(mCurrentUserId);
11401
11402         synchronized (this) {
11403             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11404                 try {
11405                     List apps = AppGlobals.getPackageManager().
11406                         getPersistentApplications(STOCK_PM_FLAGS);
11407                     if (apps != null) {
11408                         int N = apps.size();
11409                         int i;
11410                         for (i=0; i<N; i++) {
11411                             ApplicationInfo info
11412                                 = (ApplicationInfo)apps.get(i);
11413                             if (info != null &&
11414                                     !info.packageName.equals("android")) {
11415                                 addAppLocked(info, false, null /* ABI override */);
11416                             }
11417                         }
11418                     }
11419                 } catch (RemoteException ex) {
11420                     // pm is in same process, this will never happen.
11421                 }
11422             }
11423
11424             // Start up initial activity.
11425             mBooting = true;
11426             startHomeActivityLocked(mCurrentUserId, "systemReady");
11427
11428             try {
11429                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11430                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11431                             + " data partition or your device will be unstable.");
11432                     mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11433                 }
11434             } catch (RemoteException e) {
11435             }
11436
11437             if (!Build.isFingerprintConsistent()) {
11438                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11439                 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11440             }
11441
11442             long ident = Binder.clearCallingIdentity();
11443             try {
11444                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11445                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11446                         | Intent.FLAG_RECEIVER_FOREGROUND);
11447                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11448                 broadcastIntentLocked(null, null, intent,
11449                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11450                         false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11451                 intent = new Intent(Intent.ACTION_USER_STARTING);
11452                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11453                 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11454                 broadcastIntentLocked(null, null, intent,
11455                         null, new IIntentReceiver.Stub() {
11456                             @Override
11457                             public void performReceive(Intent intent, int resultCode, String data,
11458                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11459                                     throws RemoteException {
11460                             }
11461                         }, 0, null, null,
11462                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11463                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11464             } catch (Throwable t) {
11465                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11466             } finally {
11467                 Binder.restoreCallingIdentity(ident);
11468             }
11469             mStackSupervisor.resumeTopActivitiesLocked();
11470             sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11471         }
11472     }
11473
11474     private boolean makeAppCrashingLocked(ProcessRecord app,
11475             String shortMsg, String longMsg, String stackTrace) {
11476         app.crashing = true;
11477         app.crashingReport = generateProcessError(app,
11478                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11479         startAppProblemLocked(app);
11480         app.stopFreezingAllLocked();
11481         return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11482     }
11483
11484     private void makeAppNotRespondingLocked(ProcessRecord app,
11485             String activity, String shortMsg, String longMsg) {
11486         app.notResponding = true;
11487         app.notRespondingReport = generateProcessError(app,
11488                 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11489                 activity, shortMsg, longMsg, null);
11490         startAppProblemLocked(app);
11491         app.stopFreezingAllLocked();
11492     }
11493     
11494     /**
11495      * Generate a process error record, suitable for attachment to a ProcessRecord.
11496      * 
11497      * @param app The ProcessRecord in which the error occurred.
11498      * @param condition Crashing, Application Not Responding, etc.  Values are defined in 
11499      *                      ActivityManager.AppErrorStateInfo
11500      * @param activity The activity associated with the crash, if known.
11501      * @param shortMsg Short message describing the crash.
11502      * @param longMsg Long message describing the crash.
11503      * @param stackTrace Full crash stack trace, may be null.
11504      *
11505      * @return Returns a fully-formed AppErrorStateInfo record.
11506      */
11507     private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 
11508             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11509         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11510
11511         report.condition = condition;
11512         report.processName = app.processName;
11513         report.pid = app.pid;
11514         report.uid = app.info.uid;
11515         report.tag = activity;
11516         report.shortMsg = shortMsg;
11517         report.longMsg = longMsg;
11518         report.stackTrace = stackTrace;
11519
11520         return report;
11521     }
11522
11523     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11524         synchronized (this) {
11525             app.crashing = false;
11526             app.crashingReport = null;
11527             app.notResponding = false;
11528             app.notRespondingReport = null;
11529             if (app.anrDialog == fromDialog) {
11530                 app.anrDialog = null;
11531             }
11532             if (app.waitDialog == fromDialog) {
11533                 app.waitDialog = null;
11534             }
11535             if (app.pid > 0 && app.pid != MY_PID) {
11536                 handleAppCrashLocked(app, null, null, null);
11537                 app.kill("user request after error", true);
11538             }
11539         }
11540     }
11541
11542     private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11543             String stackTrace) {
11544         long now = SystemClock.uptimeMillis();
11545
11546         Long crashTime;
11547         if (!app.isolated) {
11548             crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11549         } else {
11550             crashTime = null;
11551         }
11552         if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11553             // This process loses!
11554             Slog.w(TAG, "Process " + app.info.processName
11555                     + " has crashed too many times: killing!");
11556             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11557                     app.userId, app.info.processName, app.uid);
11558             mStackSupervisor.handleAppCrashLocked(app);
11559             if (!app.persistent) {
11560                 // We don't want to start this process again until the user
11561                 // explicitly does so...  but for persistent process, we really
11562                 // need to keep it running.  If a persistent process is actually
11563                 // repeatedly crashing, then badness for everyone.
11564                 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11565                         app.info.processName);
11566                 if (!app.isolated) {
11567                     // XXX We don't have a way to mark isolated processes
11568                     // as bad, since they don't have a peristent identity.
11569                     mBadProcesses.put(app.info.processName, app.uid,
11570                             new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11571                     mProcessCrashTimes.remove(app.info.processName, app.uid);
11572                 }
11573                 app.bad = true;
11574                 app.removed = true;
11575                 // Don't let services in this process be restarted and potentially
11576                 // annoy the user repeatedly.  Unless it is persistent, since those
11577                 // processes run critical code.
11578                 removeProcessLocked(app, false, false, "crash");
11579                 mStackSupervisor.resumeTopActivitiesLocked();
11580                 return false;
11581             }
11582             mStackSupervisor.resumeTopActivitiesLocked();
11583         } else {
11584             mStackSupervisor.finishTopRunningActivityLocked(app);
11585         }
11586
11587         // Bump up the crash count of any services currently running in the proc.
11588         for (int i=app.services.size()-1; i>=0; i--) {
11589             // Any services running in the application need to be placed
11590             // back in the pending list.
11591             ServiceRecord sr = app.services.valueAt(i);
11592             sr.crashCount++;
11593         }
11594
11595         // If the crashing process is what we consider to be the "home process" and it has been
11596         // replaced by a third-party app, clear the package preferred activities from packages
11597         // with a home activity running in the process to prevent a repeatedly crashing app
11598         // from blocking the user to manually clear the list.
11599         final ArrayList<ActivityRecord> activities = app.activities;
11600         if (app == mHomeProcess && activities.size() > 0
11601                     && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11602             for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11603                 final ActivityRecord r = activities.get(activityNdx);
11604                 if (r.isHomeActivity()) {
11605                     Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11606                     try {
11607                         ActivityThread.getPackageManager()
11608                                 .clearPackagePreferredActivities(r.packageName);
11609                     } catch (RemoteException c) {
11610                         // pm is in same process, this will never happen.
11611                     }
11612                 }
11613             }
11614         }
11615
11616         if (!app.isolated) {
11617             // XXX Can't keep track of crash times for isolated processes,
11618             // because they don't have a perisistent identity.
11619             mProcessCrashTimes.put(app.info.processName, app.uid, now);
11620         }
11621
11622         if (app.crashHandler != null) mHandler.post(app.crashHandler);
11623         return true;
11624     }
11625
11626     void startAppProblemLocked(ProcessRecord app) {
11627         // If this app is not running under the current user, then we
11628         // can't give it a report button because that would require
11629         // launching the report UI under a different user.
11630         app.errorReportReceiver = null;
11631
11632         for (int userId : mCurrentProfileIds) {
11633             if (app.userId == userId) {
11634                 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11635                         mContext, app.info.packageName, app.info.flags);
11636             }
11637         }
11638         skipCurrentReceiverLocked(app);
11639     }
11640
11641     void skipCurrentReceiverLocked(ProcessRecord app) {
11642         for (BroadcastQueue queue : mBroadcastQueues) {
11643             queue.skipCurrentReceiverLocked(app);
11644         }
11645     }
11646
11647     /**
11648      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11649      * The application process will exit immediately after this call returns.
11650      * @param app object of the crashing app, null for the system server
11651      * @param crashInfo describing the exception
11652      */
11653     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11654         ProcessRecord r = findAppProcess(app, "Crash");
11655         final String processName = app == null ? "system_server"
11656                 : (r == null ? "unknown" : r.processName);
11657
11658         handleApplicationCrashInner("crash", r, processName, crashInfo);
11659     }
11660
11661     /* Native crash reporting uses this inner version because it needs to be somewhat
11662      * decoupled from the AM-managed cleanup lifecycle
11663      */
11664     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11665             ApplicationErrorReport.CrashInfo crashInfo) {
11666         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11667                 UserHandle.getUserId(Binder.getCallingUid()), processName,
11668                 r == null ? -1 : r.info.flags,
11669                 crashInfo.exceptionClassName,
11670                 crashInfo.exceptionMessage,
11671                 crashInfo.throwFileName,
11672                 crashInfo.throwLineNumber);
11673
11674         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11675
11676         crashApplication(r, crashInfo);
11677     }
11678
11679     public void handleApplicationStrictModeViolation(
11680             IBinder app,
11681             int violationMask,
11682             StrictMode.ViolationInfo info) {
11683         ProcessRecord r = findAppProcess(app, "StrictMode");
11684         if (r == null) {
11685             return;
11686         }
11687
11688         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11689             Integer stackFingerprint = info.hashCode();
11690             boolean logIt = true;
11691             synchronized (mAlreadyLoggedViolatedStacks) {
11692                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11693                     logIt = false;
11694                     // TODO: sub-sample into EventLog for these, with
11695                     // the info.durationMillis?  Then we'd get
11696                     // the relative pain numbers, without logging all
11697                     // the stack traces repeatedly.  We'd want to do
11698                     // likewise in the client code, which also does
11699                     // dup suppression, before the Binder call.
11700                 } else {
11701                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11702                         mAlreadyLoggedViolatedStacks.clear();
11703                     }
11704                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11705                 }
11706             }
11707             if (logIt) {
11708                 logStrictModeViolationToDropBox(r, info);
11709             }
11710         }
11711
11712         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11713             AppErrorResult result = new AppErrorResult();
11714             synchronized (this) {
11715                 final long origId = Binder.clearCallingIdentity();
11716
11717                 Message msg = Message.obtain();
11718                 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11719                 HashMap<String, Object> data = new HashMap<String, Object>();
11720                 data.put("result", result);
11721                 data.put("app", r);
11722                 data.put("violationMask", violationMask);
11723                 data.put("info", info);
11724                 msg.obj = data;
11725                 mHandler.sendMessage(msg);
11726
11727                 Binder.restoreCallingIdentity(origId);
11728             }
11729             int res = result.get();
11730             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11731         }
11732     }
11733
11734     // Depending on the policy in effect, there could be a bunch of
11735     // these in quick succession so we try to batch these together to
11736     // minimize disk writes, number of dropbox entries, and maximize
11737     // compression, by having more fewer, larger records.
11738     private void logStrictModeViolationToDropBox(
11739             ProcessRecord process,
11740             StrictMode.ViolationInfo info) {
11741         if (info == null) {
11742             return;
11743         }
11744         final boolean isSystemApp = process == null ||
11745                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11746                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11747         final String processName = process == null ? "unknown" : process.processName;
11748         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11749         final DropBoxManager dbox = (DropBoxManager)
11750                 mContext.getSystemService(Context.DROPBOX_SERVICE);
11751
11752         // Exit early if the dropbox isn't configured to accept this report type.
11753         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11754
11755         boolean bufferWasEmpty;
11756         boolean needsFlush;
11757         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11758         synchronized (sb) {
11759             bufferWasEmpty = sb.length() == 0;
11760             appendDropBoxProcessHeaders(process, processName, sb);
11761             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11762             sb.append("System-App: ").append(isSystemApp).append("\n");
11763             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11764             if (info.violationNumThisLoop != 0) {
11765                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11766             }
11767             if (info.numAnimationsRunning != 0) {
11768                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11769             }
11770             if (info.broadcastIntentAction != null) {
11771                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11772             }
11773             if (info.durationMillis != -1) {
11774                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11775             }
11776             if (info.numInstances != -1) {
11777                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11778             }
11779             if (info.tags != null) {
11780                 for (String tag : info.tags) {
11781                     sb.append("Span-Tag: ").append(tag).append("\n");
11782                 }
11783             }
11784             sb.append("\n");
11785             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11786                 sb.append(info.crashInfo.stackTrace);
11787             }
11788             sb.append("\n");
11789
11790             // Only buffer up to ~64k.  Various logging bits truncate
11791             // things at 128k.
11792             needsFlush = (sb.length() > 64 * 1024);
11793         }
11794
11795         // Flush immediately if the buffer's grown too large, or this
11796         // is a non-system app.  Non-system apps are isolated with a
11797         // different tag & policy and not batched.
11798         //
11799         // Batching is useful during internal testing with
11800         // StrictMode settings turned up high.  Without batching,
11801         // thousands of separate files could be created on boot.
11802         if (!isSystemApp || needsFlush) {
11803             new Thread("Error dump: " + dropboxTag) {
11804                 @Override
11805                 public void run() {
11806                     String report;
11807                     synchronized (sb) {
11808                         report = sb.toString();
11809                         sb.delete(0, sb.length());
11810                         sb.trimToSize();
11811                     }
11812                     if (report.length() != 0) {
11813                         dbox.addText(dropboxTag, report);
11814                     }
11815                 }
11816             }.start();
11817             return;
11818         }
11819
11820         // System app batching:
11821         if (!bufferWasEmpty) {
11822             // An existing dropbox-writing thread is outstanding, so
11823             // we don't need to start it up.  The existing thread will
11824             // catch the buffer appends we just did.
11825             return;
11826         }
11827
11828         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11829         // (After this point, we shouldn't access AMS internal data structures.)
11830         new Thread("Error dump: " + dropboxTag) {
11831             @Override
11832             public void run() {
11833                 // 5 second sleep to let stacks arrive and be batched together
11834                 try {
11835                     Thread.sleep(5000);  // 5 seconds
11836                 } catch (InterruptedException e) {}
11837
11838                 String errorReport;
11839                 synchronized (mStrictModeBuffer) {
11840                     errorReport = mStrictModeBuffer.toString();
11841                     if (errorReport.length() == 0) {
11842                         return;
11843                     }
11844                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11845                     mStrictModeBuffer.trimToSize();
11846                 }
11847                 dbox.addText(dropboxTag, errorReport);
11848             }
11849         }.start();
11850     }
11851
11852     /**
11853      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11854      * @param app object of the crashing app, null for the system server
11855      * @param tag reported by the caller
11856      * @param system whether this wtf is coming from the system
11857      * @param crashInfo describing the context of the error
11858      * @return true if the process should exit immediately (WTF is fatal)
11859      */
11860     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11861             final ApplicationErrorReport.CrashInfo crashInfo) {
11862         final int callingUid = Binder.getCallingUid();
11863         final int callingPid = Binder.getCallingPid();
11864
11865         if (system) {
11866             // If this is coming from the system, we could very well have low-level
11867             // system locks held, so we want to do this all asynchronously.  And we
11868             // never want this to become fatal, so there is that too.
11869             mHandler.post(new Runnable() {
11870                 @Override public void run() {
11871                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11872                 }
11873             });
11874             return false;
11875         }
11876
11877         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11878                 crashInfo);
11879
11880         if (r != null && r.pid != Process.myPid() &&
11881                 Settings.Global.getInt(mContext.getContentResolver(),
11882                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
11883             crashApplication(r, crashInfo);
11884             return true;
11885         } else {
11886             return false;
11887         }
11888     }
11889
11890     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11891             final ApplicationErrorReport.CrashInfo crashInfo) {
11892         final ProcessRecord r = findAppProcess(app, "WTF");
11893         final String processName = app == null ? "system_server"
11894                 : (r == null ? "unknown" : r.processName);
11895
11896         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11897                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11898
11899         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11900
11901         return r;
11902     }
11903
11904     /**
11905      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11906      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11907      */
11908     private ProcessRecord findAppProcess(IBinder app, String reason) {
11909         if (app == null) {
11910             return null;
11911         }
11912
11913         synchronized (this) {
11914             final int NP = mProcessNames.getMap().size();
11915             for (int ip=0; ip<NP; ip++) {
11916                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11917                 final int NA = apps.size();
11918                 for (int ia=0; ia<NA; ia++) {
11919                     ProcessRecord p = apps.valueAt(ia);
11920                     if (p.thread != null && p.thread.asBinder() == app) {
11921                         return p;
11922                     }
11923                 }
11924             }
11925
11926             Slog.w(TAG, "Can't find mystery application for " + reason
11927                     + " from pid=" + Binder.getCallingPid()
11928                     + " uid=" + Binder.getCallingUid() + ": " + app);
11929             return null;
11930         }
11931     }
11932
11933     /**
11934      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11935      * to append various headers to the dropbox log text.
11936      */
11937     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11938             StringBuilder sb) {
11939         // Watchdog thread ends up invoking this function (with
11940         // a null ProcessRecord) to add the stack file to dropbox.
11941         // Do not acquire a lock on this (am) in such cases, as it
11942         // could cause a potential deadlock, if and when watchdog
11943         // is invoked due to unavailability of lock on am and it
11944         // would prevent watchdog from killing system_server.
11945         if (process == null) {
11946             sb.append("Process: ").append(processName).append("\n");
11947             return;
11948         }
11949         // Note: ProcessRecord 'process' is guarded by the service
11950         // instance.  (notably process.pkgList, which could otherwise change
11951         // concurrently during execution of this method)
11952         synchronized (this) {
11953             sb.append("Process: ").append(processName).append("\n");
11954             int flags = process.info.flags;
11955             IPackageManager pm = AppGlobals.getPackageManager();
11956             sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11957             for (int ip=0; ip<process.pkgList.size(); ip++) {
11958                 String pkg = process.pkgList.keyAt(ip);
11959                 sb.append("Package: ").append(pkg);
11960                 try {
11961                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11962                     if (pi != null) {
11963                         sb.append(" v").append(pi.versionCode);
11964                         if (pi.versionName != null) {
11965                             sb.append(" (").append(pi.versionName).append(")");
11966                         }
11967                     }
11968                 } catch (RemoteException e) {
11969                     Slog.e(TAG, "Error getting package info: " + pkg, e);
11970                 }
11971                 sb.append("\n");
11972             }
11973         }
11974     }
11975
11976     private static String processClass(ProcessRecord process) {
11977         if (process == null || process.pid == MY_PID) {
11978             return "system_server";
11979         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11980             return "system_app";
11981         } else {
11982             return "data_app";
11983         }
11984     }
11985
11986     /**
11987      * Write a description of an error (crash, WTF, ANR) to the drop box.
11988      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11989      * @param process which caused the error, null means the system server
11990      * @param activity which triggered the error, null if unknown
11991      * @param parent activity related to the error, null if unknown
11992      * @param subject line related to the error, null if absent
11993      * @param report in long form describing the error, null if absent
11994      * @param logFile to include in the report, null if none
11995      * @param crashInfo giving an application stack trace, null if absent
11996      */
11997     public void addErrorToDropBox(String eventType,
11998             ProcessRecord process, String processName, ActivityRecord activity,
11999             ActivityRecord parent, String subject,
12000             final String report, final File logFile,
12001             final ApplicationErrorReport.CrashInfo crashInfo) {
12002         // NOTE -- this must never acquire the ActivityManagerService lock,
12003         // otherwise the watchdog may be prevented from resetting the system.
12004
12005         final String dropboxTag = processClass(process) + "_" + eventType;
12006         final DropBoxManager dbox = (DropBoxManager)
12007                 mContext.getSystemService(Context.DROPBOX_SERVICE);
12008
12009         // Exit early if the dropbox isn't configured to accept this report type.
12010         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12011
12012         final StringBuilder sb = new StringBuilder(1024);
12013         appendDropBoxProcessHeaders(process, processName, sb);
12014         if (activity != null) {
12015             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12016         }
12017         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12018             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12019         }
12020         if (parent != null && parent != activity) {
12021             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12022         }
12023         if (subject != null) {
12024             sb.append("Subject: ").append(subject).append("\n");
12025         }
12026         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12027         if (Debug.isDebuggerConnected()) {
12028             sb.append("Debugger: Connected\n");
12029         }
12030         sb.append("\n");
12031
12032         // Do the rest in a worker thread to avoid blocking the caller on I/O
12033         // (After this point, we shouldn't access AMS internal data structures.)
12034         Thread worker = new Thread("Error dump: " + dropboxTag) {
12035             @Override
12036             public void run() {
12037                 if (report != null) {
12038                     sb.append(report);
12039                 }
12040                 if (logFile != null) {
12041                     try {
12042                         sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12043                                     "\n\n[[TRUNCATED]]"));
12044                     } catch (IOException e) {
12045                         Slog.e(TAG, "Error reading " + logFile, e);
12046                     }
12047                 }
12048                 if (crashInfo != null && crashInfo.stackTrace != null) {
12049                     sb.append(crashInfo.stackTrace);
12050                 }
12051
12052                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12053                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12054                 if (lines > 0) {
12055                     sb.append("\n");
12056
12057                     // Merge several logcat streams, and take the last N lines
12058                     InputStreamReader input = null;
12059                     try {
12060                         java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12061                                 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12062                                 "-b", "crash",
12063                                 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12064
12065                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
12066                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
12067                         input = new InputStreamReader(logcat.getInputStream());
12068
12069                         int num;
12070                         char[] buf = new char[8192];
12071                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12072                     } catch (IOException e) {
12073                         Slog.e(TAG, "Error running logcat", e);
12074                     } finally {
12075                         if (input != null) try { input.close(); } catch (IOException e) {}
12076                     }
12077                 }
12078
12079                 dbox.addText(dropboxTag, sb.toString());
12080             }
12081         };
12082
12083         if (process == null) {
12084             // If process is null, we are being called from some internal code
12085             // and may be about to die -- run this synchronously.
12086             worker.run();
12087         } else {
12088             worker.start();
12089         }
12090     }
12091
12092     /**
12093      * Bring up the "unexpected error" dialog box for a crashing app.
12094      * Deal with edge cases (intercepts from instrumented applications,
12095      * ActivityController, error intent receivers, that sort of thing).
12096      * @param r the application crashing
12097      * @param crashInfo describing the failure
12098      */
12099     private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12100         long timeMillis = System.currentTimeMillis();
12101         String shortMsg = crashInfo.exceptionClassName;
12102         String longMsg = crashInfo.exceptionMessage;
12103         String stackTrace = crashInfo.stackTrace;
12104         if (shortMsg != null && longMsg != null) {
12105             longMsg = shortMsg + ": " + longMsg;
12106         } else if (shortMsg != null) {
12107             longMsg = shortMsg;
12108         }
12109
12110         AppErrorResult result = new AppErrorResult();
12111         synchronized (this) {
12112             if (mController != null) {
12113                 try {
12114                     String name = r != null ? r.processName : null;
12115                     int pid = r != null ? r.pid : Binder.getCallingPid();
12116                     int uid = r != null ? r.info.uid : Binder.getCallingUid();
12117                     if (!mController.appCrashed(name, pid,
12118                             shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12119                         if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12120                                 && "Native crash".equals(crashInfo.exceptionClassName)) {
12121                             Slog.w(TAG, "Skip killing native crashed app " + name
12122                                     + "(" + pid + ") during testing");
12123                         } else {
12124                             Slog.w(TAG, "Force-killing crashed app " + name
12125                                     + " at watcher's request");
12126                             if (r != null) {
12127                                 r.kill("crash", true);
12128                             } else {
12129                                 // Huh.
12130                                 Process.killProcess(pid);
12131                                 Process.killProcessGroup(uid, pid);
12132                             }
12133                         }
12134                         return;
12135                     }
12136                 } catch (RemoteException e) {
12137                     mController = null;
12138                     Watchdog.getInstance().setActivityController(null);
12139                 }
12140             }
12141
12142             final long origId = Binder.clearCallingIdentity();
12143
12144             // If this process is running instrumentation, finish it.
12145             if (r != null && r.instrumentationClass != null) {
12146                 Slog.w(TAG, "Error in app " + r.processName
12147                       + " running instrumentation " + r.instrumentationClass + ":");
12148                 if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12149                 if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12150                 Bundle info = new Bundle();
12151                 info.putString("shortMsg", shortMsg);
12152                 info.putString("longMsg", longMsg);
12153                 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12154                 Binder.restoreCallingIdentity(origId);
12155                 return;
12156             }
12157
12158             // Log crash in battery stats.
12159             if (r != null) {
12160                 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12161             }
12162
12163             // If we can't identify the process or it's already exceeded its crash quota,
12164             // quit right away without showing a crash dialog.
12165             if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12166                 Binder.restoreCallingIdentity(origId);
12167                 return;
12168             }
12169
12170             Message msg = Message.obtain();
12171             msg.what = SHOW_ERROR_MSG;
12172             HashMap data = new HashMap();
12173             data.put("result", result);
12174             data.put("app", r);
12175             msg.obj = data;
12176             mHandler.sendMessage(msg);
12177
12178             Binder.restoreCallingIdentity(origId);
12179         }
12180
12181         int res = result.get();
12182
12183         Intent appErrorIntent = null;
12184         synchronized (this) {
12185             if (r != null && !r.isolated) {
12186                 // XXX Can't keep track of crash time for isolated processes,
12187                 // since they don't have a persistent identity.
12188                 mProcessCrashTimes.put(r.info.processName, r.uid,
12189                         SystemClock.uptimeMillis());
12190             }
12191             if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12192                 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12193             }
12194         }
12195
12196         if (appErrorIntent != null) {
12197             try {
12198                 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12199             } catch (ActivityNotFoundException e) {
12200                 Slog.w(TAG, "bug report receiver dissappeared", e);
12201             }
12202         }
12203     }
12204
12205     Intent createAppErrorIntentLocked(ProcessRecord r,
12206             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12207         ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12208         if (report == null) {
12209             return null;
12210         }
12211         Intent result = new Intent(Intent.ACTION_APP_ERROR);
12212         result.setComponent(r.errorReportReceiver);
12213         result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12214         result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12215         return result;
12216     }
12217
12218     private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12219             long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12220         if (r.errorReportReceiver == null) {
12221             return null;
12222         }
12223
12224         if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12225             return null;
12226         }
12227
12228         ApplicationErrorReport report = new ApplicationErrorReport();
12229         report.packageName = r.info.packageName;
12230         report.installerPackageName = r.errorReportReceiver.getPackageName();
12231         report.processName = r.processName;
12232         report.time = timeMillis;
12233         report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12234
12235         if (r.crashing || r.forceCrashReport) {
12236             report.type = ApplicationErrorReport.TYPE_CRASH;
12237             report.crashInfo = crashInfo;
12238         } else if (r.notResponding) {
12239             report.type = ApplicationErrorReport.TYPE_ANR;
12240             report.anrInfo = new ApplicationErrorReport.AnrInfo();
12241
12242             report.anrInfo.activity = r.notRespondingReport.tag;
12243             report.anrInfo.cause = r.notRespondingReport.shortMsg;
12244             report.anrInfo.info = r.notRespondingReport.longMsg;
12245         }
12246
12247         return report;
12248     }
12249
12250     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12251         enforceNotIsolatedCaller("getProcessesInErrorState");
12252         // assume our apps are happy - lazy create the list
12253         List<ActivityManager.ProcessErrorStateInfo> errList = null;
12254
12255         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12256                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12257         int userId = UserHandle.getUserId(Binder.getCallingUid());
12258
12259         synchronized (this) {
12260
12261             // iterate across all processes
12262             for (int i=mLruProcesses.size()-1; i>=0; i--) {
12263                 ProcessRecord app = mLruProcesses.get(i);
12264                 if (!allUsers && app.userId != userId) {
12265                     continue;
12266                 }
12267                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12268                     // This one's in trouble, so we'll generate a report for it
12269                     // crashes are higher priority (in case there's a crash *and* an anr)
12270                     ActivityManager.ProcessErrorStateInfo report = null;
12271                     if (app.crashing) {
12272                         report = app.crashingReport;
12273                     } else if (app.notResponding) {
12274                         report = app.notRespondingReport;
12275                     }
12276                     
12277                     if (report != null) {
12278                         if (errList == null) {
12279                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12280                         }
12281                         errList.add(report);
12282                     } else {
12283                         Slog.w(TAG, "Missing app error report, app = " + app.processName + 
12284                                 " crashing = " + app.crashing +
12285                                 " notResponding = " + app.notResponding);
12286                     }
12287                 }
12288             }
12289         }
12290
12291         return errList;
12292     }
12293
12294     static int procStateToImportance(int procState, int memAdj,
12295             ActivityManager.RunningAppProcessInfo currApp) {
12296         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12297         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12298             currApp.lru = memAdj;
12299         } else {
12300             currApp.lru = 0;
12301         }
12302         return imp;
12303     }
12304
12305     private void fillInProcMemInfo(ProcessRecord app,
12306             ActivityManager.RunningAppProcessInfo outInfo) {
12307         outInfo.pid = app.pid;
12308         outInfo.uid = app.info.uid;
12309         if (mHeavyWeightProcess == app) {
12310             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12311         }
12312         if (app.persistent) {
12313             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12314         }
12315         if (app.activities.size() > 0) {
12316             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12317         }
12318         outInfo.lastTrimLevel = app.trimMemoryLevel;
12319         int adj = app.curAdj;
12320         int procState = app.curProcState;
12321         outInfo.importance = procStateToImportance(procState, adj, outInfo);
12322         outInfo.importanceReasonCode = app.adjTypeCode;
12323         outInfo.processState = app.curProcState;
12324     }
12325
12326     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12327         enforceNotIsolatedCaller("getRunningAppProcesses");
12328
12329         final int callingUid = Binder.getCallingUid();
12330
12331         // Lazy instantiation of list
12332         List<ActivityManager.RunningAppProcessInfo> runList = null;
12333         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12334                 callingUid) == PackageManager.PERMISSION_GRANTED;
12335         final int userId = UserHandle.getUserId(callingUid);
12336         final boolean allUids = isGetTasksAllowed(
12337                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12338
12339         synchronized (this) {
12340             // Iterate across all processes
12341             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12342                 ProcessRecord app = mLruProcesses.get(i);
12343                 if ((!allUsers && app.userId != userId)
12344                         || (!allUids && app.uid != callingUid)) {
12345                     continue;
12346                 }
12347                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12348                     // Generate process state info for running application
12349                     ActivityManager.RunningAppProcessInfo currApp = 
12350                         new ActivityManager.RunningAppProcessInfo(app.processName,
12351                                 app.pid, app.getPackageList());
12352                     fillInProcMemInfo(app, currApp);
12353                     if (app.adjSource instanceof ProcessRecord) {
12354                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12355                         currApp.importanceReasonImportance =
12356                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12357                                         app.adjSourceProcState);
12358                     } else if (app.adjSource instanceof ActivityRecord) {
12359                         ActivityRecord r = (ActivityRecord)app.adjSource;
12360                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12361                     }
12362                     if (app.adjTarget instanceof ComponentName) {
12363                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12364                     }
12365                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12366                     //        + " lru=" + currApp.lru);
12367                     if (runList == null) {
12368                         runList = new ArrayList<>();
12369                     }
12370                     runList.add(currApp);
12371                 }
12372             }
12373         }
12374         return runList;
12375     }
12376
12377     public List<ApplicationInfo> getRunningExternalApplications() {
12378         enforceNotIsolatedCaller("getRunningExternalApplications");
12379         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12380         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12381         if (runningApps != null && runningApps.size() > 0) {
12382             Set<String> extList = new HashSet<String>();
12383             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12384                 if (app.pkgList != null) {
12385                     for (String pkg : app.pkgList) {
12386                         extList.add(pkg);
12387                     }
12388                 }
12389             }
12390             IPackageManager pm = AppGlobals.getPackageManager();
12391             for (String pkg : extList) {
12392                 try {
12393                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12394                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12395                         retList.add(info);
12396                     }
12397                 } catch (RemoteException e) {
12398                 }
12399             }
12400         }
12401         return retList;
12402     }
12403
12404     @Override
12405     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12406         enforceNotIsolatedCaller("getMyMemoryState");
12407         synchronized (this) {
12408             ProcessRecord proc;
12409             synchronized (mPidsSelfLocked) {
12410                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12411             }
12412             fillInProcMemInfo(proc, outInfo);
12413         }
12414     }
12415
12416     @Override
12417     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12418         if (checkCallingPermission(android.Manifest.permission.DUMP)
12419                 != PackageManager.PERMISSION_GRANTED) {
12420             pw.println("Permission Denial: can't dump ActivityManager from from pid="
12421                     + Binder.getCallingPid()
12422                     + ", uid=" + Binder.getCallingUid()
12423                     + " without permission "
12424                     + android.Manifest.permission.DUMP);
12425             return;
12426         }
12427
12428         boolean dumpAll = false;
12429         boolean dumpClient = false;
12430         String dumpPackage = null;
12431         
12432         int opti = 0;
12433         while (opti < args.length) {
12434             String opt = args[opti];
12435             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12436                 break;
12437             }
12438             opti++;
12439             if ("-a".equals(opt)) {
12440                 dumpAll = true;
12441             } else if ("-c".equals(opt)) {
12442                 dumpClient = true;
12443             } else if ("-p".equals(opt)) {
12444                 if (opti < args.length) {
12445                     dumpPackage = args[opti];
12446                     opti++;
12447                 } else {
12448                     pw.println("Error: -p option requires package argument");
12449                     return;
12450                 }
12451                 dumpClient = true;
12452             } else if ("-h".equals(opt)) {
12453                 pw.println("Activity manager dump options:");
12454                 pw.println("  [-a] [-c] [-p package] [-h] [cmd] ...");
12455                 pw.println("  cmd may be one of:");
12456                 pw.println("    a[ctivities]: activity stack state");
12457                 pw.println("    r[recents]: recent activities state");
12458                 pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12459                 pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12460                 pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12461                 pw.println("    o[om]: out of memory management");
12462                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12463                 pw.println("    provider [COMP_SPEC]: provider client-side state");
12464                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12465                 pw.println("    as[sociations]: tracked app associations");
12466                 pw.println("    service [COMP_SPEC]: service client-side state");
12467                 pw.println("    package [PACKAGE_NAME]: all state related to given package");
12468                 pw.println("    all: dump all activities");
12469                 pw.println("    top: dump the top activity");
12470                 pw.println("    write: write all pending state to storage");
12471                 pw.println("    track-associations: enable association tracking");
12472                 pw.println("    untrack-associations: disable and clear association tracking");
12473                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12474                 pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12475                 pw.println("    a partial substring in a component name, a");
12476                 pw.println("    hex object identifier.");
12477                 pw.println("  -a: include all available server state.");
12478                 pw.println("  -c: include client state.");
12479                 pw.println("  -p: limit output to given package.");
12480                 return;
12481             } else {
12482                 pw.println("Unknown argument: " + opt + "; use -h for help");
12483             }
12484         }
12485
12486         long origId = Binder.clearCallingIdentity();
12487         boolean more = false;
12488         // Is the caller requesting to dump a particular piece of data?
12489         if (opti < args.length) {
12490             String cmd = args[opti];
12491             opti++;
12492             if ("activities".equals(cmd) || "a".equals(cmd)) {
12493                 synchronized (this) {
12494                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12495                 }
12496             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12497                 synchronized (this) {
12498                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12499                 }
12500             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12501                 String[] newArgs;
12502                 String name;
12503                 if (opti >= args.length) {
12504                     name = null;
12505                     newArgs = EMPTY_STRING_ARRAY;
12506                 } else {
12507                     dumpPackage = args[opti];
12508                     opti++;
12509                     newArgs = new String[args.length - opti];
12510                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12511                             args.length - opti);
12512                 }
12513                 synchronized (this) {
12514                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12515                 }
12516             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12517                 String[] newArgs;
12518                 String name;
12519                 if (opti >= args.length) {
12520                     name = null;
12521                     newArgs = EMPTY_STRING_ARRAY;
12522                 } else {
12523                     dumpPackage = args[opti];
12524                     opti++;
12525                     newArgs = new String[args.length - opti];
12526                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12527                             args.length - opti);
12528                 }
12529                 synchronized (this) {
12530                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12531                 }
12532             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12533                 String[] newArgs;
12534                 String name;
12535                 if (opti >= args.length) {
12536                     name = null;
12537                     newArgs = EMPTY_STRING_ARRAY;
12538                 } else {
12539                     dumpPackage = args[opti];
12540                     opti++;
12541                     newArgs = new String[args.length - opti];
12542                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12543                             args.length - opti);
12544                 }
12545                 synchronized (this) {
12546                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12547                 }
12548             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12549                 synchronized (this) {
12550                     dumpOomLocked(fd, pw, args, opti, true);
12551                 }
12552             } else if ("provider".equals(cmd)) {
12553                 String[] newArgs;
12554                 String name;
12555                 if (opti >= args.length) {
12556                     name = null;
12557                     newArgs = EMPTY_STRING_ARRAY;
12558                 } else {
12559                     name = args[opti];
12560                     opti++;
12561                     newArgs = new String[args.length - opti];
12562                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12563                 }
12564                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12565                     pw.println("No providers match: " + name);
12566                     pw.println("Use -h for help.");
12567                 }
12568             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12569                 synchronized (this) {
12570                     dumpProvidersLocked(fd, pw, args, opti, true, null);
12571                 }
12572             } else if ("service".equals(cmd)) {
12573                 String[] newArgs;
12574                 String name;
12575                 if (opti >= args.length) {
12576                     name = null;
12577                     newArgs = EMPTY_STRING_ARRAY;
12578                 } else {
12579                     name = args[opti];
12580                     opti++;
12581                     newArgs = new String[args.length - opti];
12582                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12583                             args.length - opti);
12584                 }
12585                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12586                     pw.println("No services match: " + name);
12587                     pw.println("Use -h for help.");
12588                 }
12589             } else if ("package".equals(cmd)) {
12590                 String[] newArgs;
12591                 if (opti >= args.length) {
12592                     pw.println("package: no package name specified");
12593                     pw.println("Use -h for help.");
12594                 } else {
12595                     dumpPackage = args[opti];
12596                     opti++;
12597                     newArgs = new String[args.length - opti];
12598                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12599                             args.length - opti);
12600                     args = newArgs;
12601                     opti = 0;
12602                     more = true;
12603                 }
12604             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12605                 synchronized (this) {
12606                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12607                 }
12608             } else if ("services".equals(cmd) || "s".equals(cmd)) {
12609                 synchronized (this) {
12610                     mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12611                 }
12612             } else if ("write".equals(cmd)) {
12613                 mTaskPersister.flush();
12614                 pw.println("All tasks persisted.");
12615                 return;
12616             } else if ("track-associations".equals(cmd)) {
12617                 synchronized (this) {
12618                     if (!mTrackingAssociations) {
12619                         mTrackingAssociations = true;
12620                         pw.println("Association tracking started.");
12621                     } else {
12622                         pw.println("Association tracking already enabled.");
12623                     }
12624                 }
12625                 return;
12626             } else if ("untrack-associations".equals(cmd)) {
12627                 synchronized (this) {
12628                     if (mTrackingAssociations) {
12629                         mTrackingAssociations = false;
12630                         mAssociations.clear();
12631                         pw.println("Association tracking stopped.");
12632                     } else {
12633                         pw.println("Association tracking not running.");
12634                     }
12635                 }
12636                 return;
12637             } else {
12638                 // Dumping a single activity?
12639                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12640                     pw.println("Bad activity command, or no activities match: " + cmd);
12641                     pw.println("Use -h for help.");
12642                 }
12643             }
12644             if (!more) {
12645                 Binder.restoreCallingIdentity(origId);
12646                 return;
12647             }
12648         }
12649
12650         // No piece of data specified, dump everything.
12651         synchronized (this) {
12652             dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12653             pw.println();
12654             if (dumpAll) {
12655                 pw.println("-------------------------------------------------------------------------------");
12656             }
12657             dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12658             pw.println();
12659             if (dumpAll) {
12660                 pw.println("-------------------------------------------------------------------------------");
12661             }
12662             dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12663             pw.println();
12664             if (dumpAll) {
12665                 pw.println("-------------------------------------------------------------------------------");
12666             }
12667             mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12668             pw.println();
12669             if (dumpAll) {
12670                 pw.println("-------------------------------------------------------------------------------");
12671             }
12672             dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12673             pw.println();
12674             if (dumpAll) {
12675                 pw.println("-------------------------------------------------------------------------------");
12676             }
12677             dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12678             if (mAssociations.size() > 0) {
12679                 pw.println();
12680                 if (dumpAll) {
12681                     pw.println("-------------------------------------------------------------------------------");
12682                 }
12683                 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12684             }
12685             pw.println();
12686             if (dumpAll) {
12687                 pw.println("-------------------------------------------------------------------------------");
12688             }
12689             dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12690         }
12691         Binder.restoreCallingIdentity(origId);
12692     }
12693
12694     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12695             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12696         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12697
12698         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12699                 dumpPackage);
12700         boolean needSep = printedAnything;
12701
12702         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12703                 dumpPackage, needSep, "  mFocusedActivity: ");
12704         if (printed) {
12705             printedAnything = true;
12706             needSep = false;
12707         }
12708
12709         if (dumpPackage == null) {
12710             if (needSep) {
12711                 pw.println();
12712             }
12713             needSep = true;
12714             printedAnything = true;
12715             mStackSupervisor.dump(pw, "  ");
12716         }
12717
12718         if (!printedAnything) {
12719             pw.println("  (nothing)");
12720         }
12721     }
12722
12723     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12724             int opti, boolean dumpAll, String dumpPackage) {
12725         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12726
12727         boolean printedAnything = false;
12728
12729         if (mRecentTasks != null && mRecentTasks.size() > 0) {
12730             boolean printedHeader = false;
12731
12732             final int N = mRecentTasks.size();
12733             for (int i=0; i<N; i++) {
12734                 TaskRecord tr = mRecentTasks.get(i);
12735                 if (dumpPackage != null) {
12736                     if (tr.realActivity == null ||
12737                             !dumpPackage.equals(tr.realActivity)) {
12738                         continue;
12739                     }
12740                 }
12741                 if (!printedHeader) {
12742                     pw.println("  Recent tasks:");
12743                     printedHeader = true;
12744                     printedAnything = true;
12745                 }
12746                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12747                         pw.println(tr);
12748                 if (dumpAll) {
12749                     mRecentTasks.get(i).dump(pw, "    ");
12750                 }
12751             }
12752         }
12753
12754         if (!printedAnything) {
12755             pw.println("  (nothing)");
12756         }
12757     }
12758
12759     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12760             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12761         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12762
12763         int dumpUid = 0;
12764         if (dumpPackage != null) {
12765             IPackageManager pm = AppGlobals.getPackageManager();
12766             try {
12767                 dumpUid = pm.getPackageUid(dumpPackage, 0);
12768             } catch (RemoteException e) {
12769             }
12770         }
12771
12772         boolean printedAnything = false;
12773
12774         final long now = SystemClock.uptimeMillis();
12775
12776         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12777             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12778                     = mAssociations.valueAt(i1);
12779             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12780                 SparseArray<ArrayMap<String, Association>> sourceUids
12781                         = targetComponents.valueAt(i2);
12782                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12783                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12784                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12785                         Association ass = sourceProcesses.valueAt(i4);
12786                         if (dumpPackage != null) {
12787                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12788                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12789                                 continue;
12790                             }
12791                         }
12792                         printedAnything = true;
12793                         pw.print("  ");
12794                         pw.print(ass.mTargetProcess);
12795                         pw.print("/");
12796                         UserHandle.formatUid(pw, ass.mTargetUid);
12797                         pw.print(" <- ");
12798                         pw.print(ass.mSourceProcess);
12799                         pw.print("/");
12800                         UserHandle.formatUid(pw, ass.mSourceUid);
12801                         pw.println();
12802                         pw.print("    via ");
12803                         pw.print(ass.mTargetComponent.flattenToShortString());
12804                         pw.println();
12805                         pw.print("    ");
12806                         long dur = ass.mTime;
12807                         if (ass.mNesting > 0) {
12808                             dur += now - ass.mStartTime;
12809                         }
12810                         TimeUtils.formatDuration(dur, pw);
12811                         pw.print(" (");
12812                         pw.print(ass.mCount);
12813                         pw.println(" times)");
12814                         if (ass.mNesting > 0) {
12815                             pw.print("    ");
12816                             pw.print(" Currently active: ");
12817                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
12818                             pw.println();
12819                         }
12820                     }
12821                 }
12822             }
12823
12824         }
12825
12826         if (!printedAnything) {
12827             pw.println("  (nothing)");
12828         }
12829     }
12830
12831     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12832             int opti, boolean dumpAll, String dumpPackage) {
12833         boolean needSep = false;
12834         boolean printedAnything = false;
12835         int numPers = 0;
12836
12837         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12838
12839         if (dumpAll) {
12840             final int NP = mProcessNames.getMap().size();
12841             for (int ip=0; ip<NP; ip++) {
12842                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12843                 final int NA = procs.size();
12844                 for (int ia=0; ia<NA; ia++) {
12845                     ProcessRecord r = procs.valueAt(ia);
12846                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12847                         continue;
12848                     }
12849                     if (!needSep) {
12850                         pw.println("  All known processes:");
12851                         needSep = true;
12852                         printedAnything = true;
12853                     }
12854                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12855                         pw.print(" UID "); pw.print(procs.keyAt(ia));
12856                         pw.print(" "); pw.println(r);
12857                     r.dump(pw, "    ");
12858                     if (r.persistent) {
12859                         numPers++;
12860                     }
12861                 }
12862             }
12863         }
12864
12865         if (mIsolatedProcesses.size() > 0) {
12866             boolean printed = false;
12867             for (int i=0; i<mIsolatedProcesses.size(); i++) {
12868                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12869                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12870                     continue;
12871                 }
12872                 if (!printed) {
12873                     if (needSep) {
12874                         pw.println();
12875                     }
12876                     pw.println("  Isolated process list (sorted by uid):");
12877                     printedAnything = true;
12878                     printed = true;
12879                     needSep = true;
12880                 }
12881                 pw.println(String.format("%sIsolated #%2d: %s",
12882                         "    ", i, r.toString()));
12883             }
12884         }
12885
12886         if (mLruProcesses.size() > 0) {
12887             if (needSep) {
12888                 pw.println();
12889             }
12890             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12891                     pw.print(" total, non-act at ");
12892                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12893                     pw.print(", non-svc at ");
12894                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12895                     pw.println("):");
12896             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12897             needSep = true;
12898             printedAnything = true;
12899         }
12900
12901         if (dumpAll || dumpPackage != null) {
12902             synchronized (mPidsSelfLocked) {
12903                 boolean printed = false;
12904                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12905                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
12906                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12907                         continue;
12908                     }
12909                     if (!printed) {
12910                         if (needSep) pw.println();
12911                         needSep = true;
12912                         pw.println("  PID mappings:");
12913                         printed = true;
12914                         printedAnything = true;
12915                     }
12916                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12917                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12918                 }
12919             }
12920         }
12921         
12922         if (mForegroundProcesses.size() > 0) {
12923             synchronized (mPidsSelfLocked) {
12924                 boolean printed = false;
12925                 for (int i=0; i<mForegroundProcesses.size(); i++) {
12926                     ProcessRecord r = mPidsSelfLocked.get( 
12927                             mForegroundProcesses.valueAt(i).pid);
12928                     if (dumpPackage != null && (r == null
12929                             || !r.pkgList.containsKey(dumpPackage))) {
12930                         continue;
12931                     }
12932                     if (!printed) {
12933                         if (needSep) pw.println();
12934                         needSep = true;
12935                         pw.println("  Foreground Processes:");
12936                         printed = true;
12937                         printedAnything = true;
12938                     }
12939                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12940                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12941                 }
12942             }
12943         }
12944         
12945         if (mPersistentStartingProcesses.size() > 0) {
12946             if (needSep) pw.println();
12947             needSep = true;
12948             printedAnything = true;
12949             pw.println("  Persisent processes that are starting:");
12950             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12951                     "Starting Norm", "Restarting PERS", dumpPackage);
12952         }
12953
12954         if (mRemovedProcesses.size() > 0) {
12955             if (needSep) pw.println();
12956             needSep = true;
12957             printedAnything = true;
12958             pw.println("  Processes that are being removed:");
12959             dumpProcessList(pw, this, mRemovedProcesses, "    ",
12960                     "Removed Norm", "Removed PERS", dumpPackage);
12961         }
12962         
12963         if (mProcessesOnHold.size() > 0) {
12964             if (needSep) pw.println();
12965             needSep = true;
12966             printedAnything = true;
12967             pw.println("  Processes that are on old until the system is ready:");
12968             dumpProcessList(pw, this, mProcessesOnHold, "    ",
12969                     "OnHold Norm", "OnHold PERS", dumpPackage);
12970         }
12971
12972         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12973         
12974         if (mProcessCrashTimes.getMap().size() > 0) {
12975             boolean printed = false;
12976             long now = SystemClock.uptimeMillis();
12977             final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12978             final int NP = pmap.size();
12979             for (int ip=0; ip<NP; ip++) {
12980                 String pname = pmap.keyAt(ip);
12981                 SparseArray<Long> uids = pmap.valueAt(ip);
12982                 final int N = uids.size();
12983                 for (int i=0; i<N; i++) {
12984                     int puid = uids.keyAt(i);
12985                     ProcessRecord r = mProcessNames.get(pname, puid);
12986                     if (dumpPackage != null && (r == null
12987                             || !r.pkgList.containsKey(dumpPackage))) {
12988                         continue;
12989                     }
12990                     if (!printed) {
12991                         if (needSep) pw.println();
12992                         needSep = true;
12993                         pw.println("  Time since processes crashed:");
12994                         printed = true;
12995                         printedAnything = true;
12996                     }
12997                     pw.print("    Process "); pw.print(pname);
12998                             pw.print(" uid "); pw.print(puid);
12999                             pw.print(": last crashed ");
13000                             TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13001                             pw.println(" ago");
13002                 }
13003             }
13004         }
13005
13006         if (mBadProcesses.getMap().size() > 0) {
13007             boolean printed = false;
13008             final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13009             final int NP = pmap.size();
13010             for (int ip=0; ip<NP; ip++) {
13011                 String pname = pmap.keyAt(ip);
13012                 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13013                 final int N = uids.size();
13014                 for (int i=0; i<N; i++) {
13015                     int puid = uids.keyAt(i);
13016                     ProcessRecord r = mProcessNames.get(pname, puid);
13017                     if (dumpPackage != null && (r == null
13018                             || !r.pkgList.containsKey(dumpPackage))) {
13019                         continue;
13020                     }
13021                     if (!printed) {
13022                         if (needSep) pw.println();
13023                         needSep = true;
13024                         pw.println("  Bad processes:");
13025                         printedAnything = true;
13026                     }
13027                     BadProcessInfo info = uids.valueAt(i);
13028                     pw.print("    Bad process "); pw.print(pname);
13029                             pw.print(" uid "); pw.print(puid);
13030                             pw.print(": crashed at time "); pw.println(info.time);
13031                     if (info.shortMsg != null) {
13032                         pw.print("      Short msg: "); pw.println(info.shortMsg);
13033                     }
13034                     if (info.longMsg != null) {
13035                         pw.print("      Long msg: "); pw.println(info.longMsg);
13036                     }
13037                     if (info.stack != null) {
13038                         pw.println("      Stack:");
13039                         int lastPos = 0;
13040                         for (int pos=0; pos<info.stack.length(); pos++) {
13041                             if (info.stack.charAt(pos) == '\n') {
13042                                 pw.print("        ");
13043                                 pw.write(info.stack, lastPos, pos-lastPos);
13044                                 pw.println();
13045                                 lastPos = pos+1;
13046                             }
13047                         }
13048                         if (lastPos < info.stack.length()) {
13049                             pw.print("        ");
13050                             pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13051                             pw.println();
13052                         }
13053                     }
13054                 }
13055             }
13056         }
13057
13058         if (dumpPackage == null) {
13059             pw.println();
13060             needSep = false;
13061             pw.println("  mStartedUsers:");
13062             for (int i=0; i<mStartedUsers.size(); i++) {
13063                 UserStartedState uss = mStartedUsers.valueAt(i);
13064                 pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
13065                         pw.print(": "); uss.dump("", pw);
13066             }
13067             pw.print("  mStartedUserArray: [");
13068             for (int i=0; i<mStartedUserArray.length; i++) {
13069                 if (i > 0) pw.print(", ");
13070                 pw.print(mStartedUserArray[i]);
13071             }
13072             pw.println("]");
13073             pw.print("  mUserLru: [");
13074             for (int i=0; i<mUserLru.size(); i++) {
13075                 if (i > 0) pw.print(", ");
13076                 pw.print(mUserLru.get(i));
13077             }
13078             pw.println("]");
13079             if (dumpAll) {
13080                 pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13081             }
13082             synchronized (mUserProfileGroupIdsSelfLocked) {
13083                 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13084                     pw.println("  mUserProfileGroupIds:");
13085                     for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13086                         pw.print("    User #");
13087                         pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13088                         pw.print(" -> profile #");
13089                         pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13090                     }
13091                 }
13092             }
13093         }
13094         if (mHomeProcess != null && (dumpPackage == null
13095                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13096             if (needSep) {
13097                 pw.println();
13098                 needSep = false;
13099             }
13100             pw.println("  mHomeProcess: " + mHomeProcess);
13101         }
13102         if (mPreviousProcess != null && (dumpPackage == null
13103                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13104             if (needSep) {
13105                 pw.println();
13106                 needSep = false;
13107             }
13108             pw.println("  mPreviousProcess: " + mPreviousProcess);
13109         }
13110         if (dumpAll) {
13111             StringBuilder sb = new StringBuilder(128);
13112             sb.append("  mPreviousProcessVisibleTime: ");
13113             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13114             pw.println(sb);
13115         }
13116         if (mHeavyWeightProcess != null && (dumpPackage == null
13117                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13118             if (needSep) {
13119                 pw.println();
13120                 needSep = false;
13121             }
13122             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13123         }
13124         if (dumpPackage == null) {
13125             pw.println("  mConfiguration: " + mConfiguration);
13126         }
13127         if (dumpAll) {
13128             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13129             if (mCompatModePackages.getPackages().size() > 0) {
13130                 boolean printed = false;
13131                 for (Map.Entry<String, Integer> entry
13132                         : mCompatModePackages.getPackages().entrySet()) {
13133                     String pkg = entry.getKey();
13134                     int mode = entry.getValue();
13135                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13136                         continue;
13137                     }
13138                     if (!printed) {
13139                         pw.println("  mScreenCompatPackages:");
13140                         printed = true;
13141                     }
13142                     pw.print("    "); pw.print(pkg); pw.print(": ");
13143                             pw.print(mode); pw.println();
13144                 }
13145             }
13146         }
13147         if (dumpPackage == null) {
13148             pw.println("  mWakefulness="
13149                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
13150             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
13151                     + lockScreenShownToString());
13152             pw.println("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13153                     + " mTestPssMode=" + mTestPssMode);
13154         }
13155         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13156                 || mOrigWaitForDebugger) {
13157             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13158                     || dumpPackage.equals(mOrigDebugApp)) {
13159                 if (needSep) {
13160                     pw.println();
13161                     needSep = false;
13162                 }
13163                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13164                         + " mDebugTransient=" + mDebugTransient
13165                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13166             }
13167         }
13168         if (mOpenGlTraceApp != null) {
13169             if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13170                 if (needSep) {
13171                     pw.println();
13172                     needSep = false;
13173                 }
13174                 pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
13175             }
13176         }
13177         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13178                 || mProfileFd != null) {
13179             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13180                 if (needSep) {
13181                     pw.println();
13182                     needSep = false;
13183                 }
13184                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13185                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13186                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13187                         + mAutoStopProfiler);
13188                 pw.println("  mProfileType=" + mProfileType);
13189             }
13190         }
13191         if (dumpPackage == null) {
13192             if (mAlwaysFinishActivities || mController != null) {
13193                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
13194                         + " mController=" + mController);
13195             }
13196             if (dumpAll) {
13197                 pw.println("  Total persistent processes: " + numPers);
13198                 pw.println("  mProcessesReady=" + mProcessesReady
13199                         + " mSystemReady=" + mSystemReady
13200                         + " mBooted=" + mBooted
13201                         + " mFactoryTest=" + mFactoryTest);
13202                 pw.println("  mBooting=" + mBooting
13203                         + " mCallFinishBooting=" + mCallFinishBooting
13204                         + " mBootAnimationComplete=" + mBootAnimationComplete);
13205                 pw.print("  mLastPowerCheckRealtime=");
13206                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13207                         pw.println("");
13208                 pw.print("  mLastPowerCheckUptime=");
13209                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13210                         pw.println("");
13211                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13212                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13213                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13214                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13215                         + " (" + mLruProcesses.size() + " total)"
13216                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13217                         + " mNumServiceProcs=" + mNumServiceProcs
13218                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13219                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13220                         + " mLastMemoryLevel" + mLastMemoryLevel
13221                         + " mLastNumProcesses" + mLastNumProcesses);
13222                 long now = SystemClock.uptimeMillis();
13223                 pw.print("  mLastIdleTime=");
13224                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
13225                         pw.print(" mLowRamSinceLastIdle=");
13226                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13227                         pw.println();
13228             }
13229         }
13230
13231         if (!printedAnything) {
13232             pw.println("  (nothing)");
13233         }
13234     }
13235
13236     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13237             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13238         if (mProcessesToGc.size() > 0) {
13239             boolean printed = false;
13240             long now = SystemClock.uptimeMillis();
13241             for (int i=0; i<mProcessesToGc.size(); i++) {
13242                 ProcessRecord proc = mProcessesToGc.get(i);
13243                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13244                     continue;
13245                 }
13246                 if (!printed) {
13247                     if (needSep) pw.println();
13248                     needSep = true;
13249                     pw.println("  Processes that are waiting to GC:");
13250                     printed = true;
13251                 }
13252                 pw.print("    Process "); pw.println(proc);
13253                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13254                         pw.print(", last gced=");
13255                         pw.print(now-proc.lastRequestedGc);
13256                         pw.print(" ms ago, last lowMem=");
13257                         pw.print(now-proc.lastLowMemory);
13258                         pw.println(" ms ago");
13259
13260             }
13261         }
13262         return needSep;
13263     }
13264
13265     void printOomLevel(PrintWriter pw, String name, int adj) {
13266         pw.print("    ");
13267         if (adj >= 0) {
13268             pw.print(' ');
13269             if (adj < 10) pw.print(' ');
13270         } else {
13271             if (adj > -10) pw.print(' ');
13272         }
13273         pw.print(adj);
13274         pw.print(": ");
13275         pw.print(name);
13276         pw.print(" (");
13277         pw.print(mProcessList.getMemLevel(adj)/1024);
13278         pw.println(" kB)");
13279     }
13280
13281     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13282             int opti, boolean dumpAll) {
13283         boolean needSep = false;
13284
13285         if (mLruProcesses.size() > 0) {
13286             if (needSep) pw.println();
13287             needSep = true;
13288             pw.println("  OOM levels:");
13289             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13290             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13291             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13292             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13293             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13294             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13295             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13296             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13297             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13298             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13299             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13300             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13301             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13302             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13303
13304             if (needSep) pw.println();
13305             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13306                     pw.print(" total, non-act at ");
13307                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13308                     pw.print(", non-svc at ");
13309                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13310                     pw.println("):");
13311             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13312             needSep = true;
13313         }
13314
13315         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13316
13317         pw.println();
13318         pw.println("  mHomeProcess: " + mHomeProcess);
13319         pw.println("  mPreviousProcess: " + mPreviousProcess);
13320         if (mHeavyWeightProcess != null) {
13321             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13322         }
13323
13324         return true;
13325     }
13326
13327     /**
13328      * There are three ways to call this:
13329      *  - no provider specified: dump all the providers
13330      *  - a flattened component name that matched an existing provider was specified as the
13331      *    first arg: dump that one provider
13332      *  - the first arg isn't the flattened component name of an existing provider:
13333      *    dump all providers whose component contains the first arg as a substring
13334      */
13335     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13336             int opti, boolean dumpAll) {
13337         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13338     }
13339
13340     static class ItemMatcher {
13341         ArrayList<ComponentName> components;
13342         ArrayList<String> strings;
13343         ArrayList<Integer> objects;
13344         boolean all;
13345         
13346         ItemMatcher() {
13347             all = true;
13348         }
13349
13350         void build(String name) {
13351             ComponentName componentName = ComponentName.unflattenFromString(name);
13352             if (componentName != null) {
13353                 if (components == null) {
13354                     components = new ArrayList<ComponentName>();
13355                 }
13356                 components.add(componentName);
13357                 all = false;
13358             } else {
13359                 int objectId = 0;
13360                 // Not a '/' separated full component name; maybe an object ID?
13361                 try {
13362                     objectId = Integer.parseInt(name, 16);
13363                     if (objects == null) {
13364                         objects = new ArrayList<Integer>();
13365                     }
13366                     objects.add(objectId);
13367                     all = false;
13368                 } catch (RuntimeException e) {
13369                     // Not an integer; just do string match.
13370                     if (strings == null) {
13371                         strings = new ArrayList<String>();
13372                     }
13373                     strings.add(name);
13374                     all = false;
13375                 }
13376             }
13377         }
13378
13379         int build(String[] args, int opti) {
13380             for (; opti<args.length; opti++) {
13381                 String name = args[opti];
13382                 if ("--".equals(name)) {
13383                     return opti+1;
13384                 }
13385                 build(name);
13386             }
13387             return opti;
13388         }
13389
13390         boolean match(Object object, ComponentName comp) {
13391             if (all) {
13392                 return true;
13393             }
13394             if (components != null) {
13395                 for (int i=0; i<components.size(); i++) {
13396                     if (components.get(i).equals(comp)) {
13397                         return true;
13398                     }
13399                 }
13400             }
13401             if (objects != null) {
13402                 for (int i=0; i<objects.size(); i++) {
13403                     if (System.identityHashCode(object) == objects.get(i)) {
13404                         return true;
13405                     }
13406                 }
13407             }
13408             if (strings != null) {
13409                 String flat = comp.flattenToString();
13410                 for (int i=0; i<strings.size(); i++) {
13411                     if (flat.contains(strings.get(i))) {
13412                         return true;
13413                     }
13414                 }
13415             }
13416             return false;
13417         }
13418     }
13419
13420     /**
13421      * There are three things that cmd can be:
13422      *  - a flattened component name that matches an existing activity
13423      *  - the cmd arg isn't the flattened component name of an existing activity:
13424      *    dump all activity whose component contains the cmd as a substring
13425      *  - A hex number of the ActivityRecord object instance.
13426      */
13427     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13428             int opti, boolean dumpAll) {
13429         ArrayList<ActivityRecord> activities;
13430         
13431         synchronized (this) {
13432             activities = mStackSupervisor.getDumpActivitiesLocked(name);
13433         }
13434
13435         if (activities.size() <= 0) {
13436             return false;
13437         }
13438
13439         String[] newArgs = new String[args.length - opti];
13440         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13441
13442         TaskRecord lastTask = null;
13443         boolean needSep = false;
13444         for (int i=activities.size()-1; i>=0; i--) {
13445             ActivityRecord r = activities.get(i);
13446             if (needSep) {
13447                 pw.println();
13448             }
13449             needSep = true;
13450             synchronized (this) {
13451                 if (lastTask != r.task) {
13452                     lastTask = r.task;
13453                     pw.print("TASK "); pw.print(lastTask.affinity);
13454                             pw.print(" id="); pw.println(lastTask.taskId);
13455                     if (dumpAll) {
13456                         lastTask.dump(pw, "  ");
13457                     }
13458                 }
13459             }
13460             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13461         }
13462         return true;
13463     }
13464
13465     /**
13466      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13467      * there is a thread associated with the activity.
13468      */
13469     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13470             final ActivityRecord r, String[] args, boolean dumpAll) {
13471         String innerPrefix = prefix + "  ";
13472         synchronized (this) {
13473             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13474                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13475                     pw.print(" pid=");
13476                     if (r.app != null) pw.println(r.app.pid);
13477                     else pw.println("(not running)");
13478             if (dumpAll) {
13479                 r.dump(pw, innerPrefix);
13480             }
13481         }
13482         if (r.app != null && r.app.thread != null) {
13483             // flush anything that is already in the PrintWriter since the thread is going
13484             // to write to the file descriptor directly
13485             pw.flush();
13486             try {
13487                 TransferPipe tp = new TransferPipe();
13488                 try {
13489                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13490                             r.appToken, innerPrefix, args);
13491                     tp.go(fd);
13492                 } finally {
13493                     tp.kill();
13494                 }
13495             } catch (IOException e) {
13496                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13497             } catch (RemoteException e) {
13498                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13499             }
13500         }
13501     }
13502
13503     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13504             int opti, boolean dumpAll, String dumpPackage) {
13505         boolean needSep = false;
13506         boolean onlyHistory = false;
13507         boolean printedAnything = false;
13508
13509         if ("history".equals(dumpPackage)) {
13510             if (opti < args.length && "-s".equals(args[opti])) {
13511                 dumpAll = false;
13512             }
13513             onlyHistory = true;
13514             dumpPackage = null;
13515         }
13516
13517         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13518         if (!onlyHistory && dumpAll) {
13519             if (mRegisteredReceivers.size() > 0) {
13520                 boolean printed = false;
13521                 Iterator it = mRegisteredReceivers.values().iterator();
13522                 while (it.hasNext()) {
13523                     ReceiverList r = (ReceiverList)it.next();
13524                     if (dumpPackage != null && (r.app == null ||
13525                             !dumpPackage.equals(r.app.info.packageName))) {
13526                         continue;
13527                     }
13528                     if (!printed) {
13529                         pw.println("  Registered Receivers:");
13530                         needSep = true;
13531                         printed = true;
13532                         printedAnything = true;
13533                     }
13534                     pw.print("  * "); pw.println(r);
13535                     r.dump(pw, "    ");
13536                 }
13537             }
13538
13539             if (mReceiverResolver.dump(pw, needSep ?
13540                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13541                     "    ", dumpPackage, false, false)) {
13542                 needSep = true;
13543                 printedAnything = true;
13544             }
13545         }
13546
13547         for (BroadcastQueue q : mBroadcastQueues) {
13548             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13549             printedAnything |= needSep;
13550         }
13551
13552         needSep = true;
13553         
13554         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13555             for (int user=0; user<mStickyBroadcasts.size(); user++) {
13556                 if (needSep) {
13557                     pw.println();
13558                 }
13559                 needSep = true;
13560                 printedAnything = true;
13561                 pw.print("  Sticky broadcasts for user ");
13562                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13563                 StringBuilder sb = new StringBuilder(128);
13564                 for (Map.Entry<String, ArrayList<Intent>> ent
13565                         : mStickyBroadcasts.valueAt(user).entrySet()) {
13566                     pw.print("  * Sticky action "); pw.print(ent.getKey());
13567                     if (dumpAll) {
13568                         pw.println(":");
13569                         ArrayList<Intent> intents = ent.getValue();
13570                         final int N = intents.size();
13571                         for (int i=0; i<N; i++) {
13572                             sb.setLength(0);
13573                             sb.append("    Intent: ");
13574                             intents.get(i).toShortString(sb, false, true, false, false);
13575                             pw.println(sb.toString());
13576                             Bundle bundle = intents.get(i).getExtras();
13577                             if (bundle != null) {
13578                                 pw.print("      ");
13579                                 pw.println(bundle.toString());
13580                             }
13581                         }
13582                     } else {
13583                         pw.println("");
13584                     }
13585                 }
13586             }
13587         }
13588         
13589         if (!onlyHistory && dumpAll) {
13590             pw.println();
13591             for (BroadcastQueue queue : mBroadcastQueues) {
13592                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13593                         + queue.mBroadcastsScheduled);
13594             }
13595             pw.println("  mHandler:");
13596             mHandler.dump(new PrintWriterPrinter(pw), "    ");
13597             needSep = true;
13598             printedAnything = true;
13599         }
13600         
13601         if (!printedAnything) {
13602             pw.println("  (nothing)");
13603         }
13604     }
13605
13606     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13607             int opti, boolean dumpAll, String dumpPackage) {
13608         boolean needSep;
13609         boolean printedAnything = false;
13610
13611         ItemMatcher matcher = new ItemMatcher();
13612         matcher.build(args, opti);
13613
13614         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13615
13616         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13617         printedAnything |= needSep;
13618
13619         if (mLaunchingProviders.size() > 0) {
13620             boolean printed = false;
13621             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13622                 ContentProviderRecord r = mLaunchingProviders.get(i);
13623                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13624                     continue;
13625                 }
13626                 if (!printed) {
13627                     if (needSep) pw.println();
13628                     needSep = true;
13629                     pw.println("  Launching content providers:");
13630                     printed = true;
13631                     printedAnything = true;
13632                 }
13633                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
13634                         pw.println(r);
13635             }
13636         }
13637
13638         if (mGrantedUriPermissions.size() > 0) {
13639             boolean printed = false;
13640             int dumpUid = -2;
13641             if (dumpPackage != null) {
13642                 try {
13643                     dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13644                 } catch (NameNotFoundException e) {
13645                     dumpUid = -1;
13646                 }
13647             }
13648             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13649                 int uid = mGrantedUriPermissions.keyAt(i);
13650                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13651                     continue;
13652                 }
13653                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13654                 if (!printed) {
13655                     if (needSep) pw.println();
13656                     needSep = true;
13657                     pw.println("  Granted Uri Permissions:");
13658                     printed = true;
13659                     printedAnything = true;
13660                 }
13661                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13662                 for (UriPermission perm : perms.values()) {
13663                     pw.print("    "); pw.println(perm);
13664                     if (dumpAll) {
13665                         perm.dump(pw, "      ");
13666                     }
13667                 }
13668             }
13669         }
13670
13671         if (!printedAnything) {
13672             pw.println("  (nothing)");
13673         }
13674     }
13675
13676     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13677             int opti, boolean dumpAll, String dumpPackage) {
13678         boolean printed = false;
13679
13680         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13681
13682         if (mIntentSenderRecords.size() > 0) {
13683             Iterator<WeakReference<PendingIntentRecord>> it
13684                     = mIntentSenderRecords.values().iterator();
13685             while (it.hasNext()) {
13686                 WeakReference<PendingIntentRecord> ref = it.next();
13687                 PendingIntentRecord rec = ref != null ? ref.get(): null;
13688                 if (dumpPackage != null && (rec == null
13689                         || !dumpPackage.equals(rec.key.packageName))) {
13690                     continue;
13691                 }
13692                 printed = true;
13693                 if (rec != null) {
13694                     pw.print("  * "); pw.println(rec);
13695                     if (dumpAll) {
13696                         rec.dump(pw, "    ");
13697                     }
13698                 } else {
13699                     pw.print("  * "); pw.println(ref);
13700                 }
13701             }
13702         }
13703
13704         if (!printed) {
13705             pw.println("  (nothing)");
13706         }
13707     }
13708
13709     private static final int dumpProcessList(PrintWriter pw,
13710             ActivityManagerService service, List list,
13711             String prefix, String normalLabel, String persistentLabel,
13712             String dumpPackage) {
13713         int numPers = 0;
13714         final int N = list.size()-1;
13715         for (int i=N; i>=0; i--) {
13716             ProcessRecord r = (ProcessRecord)list.get(i);
13717             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13718                 continue;
13719             }
13720             pw.println(String.format("%s%s #%2d: %s",
13721                     prefix, (r.persistent ? persistentLabel : normalLabel),
13722                     i, r.toString()));
13723             if (r.persistent) {
13724                 numPers++;
13725             }
13726         }
13727         return numPers;
13728     }
13729
13730     private static final boolean dumpProcessOomList(PrintWriter pw,
13731             ActivityManagerService service, List<ProcessRecord> origList,
13732             String prefix, String normalLabel, String persistentLabel,
13733             boolean inclDetails, String dumpPackage) {
13734
13735         ArrayList<Pair<ProcessRecord, Integer>> list
13736                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13737         for (int i=0; i<origList.size(); i++) {
13738             ProcessRecord r = origList.get(i);
13739             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13740                 continue;
13741             }
13742             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13743         }
13744
13745         if (list.size() <= 0) {
13746             return false;
13747         }
13748
13749         Comparator<Pair<ProcessRecord, Integer>> comparator
13750                 = new Comparator<Pair<ProcessRecord, Integer>>() {
13751             @Override
13752             public int compare(Pair<ProcessRecord, Integer> object1,
13753                     Pair<ProcessRecord, Integer> object2) {
13754                 if (object1.first.setAdj != object2.first.setAdj) {
13755                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13756                 }
13757                 if (object1.second.intValue() != object2.second.intValue()) {
13758                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13759                 }
13760                 return 0;
13761             }
13762         };
13763
13764         Collections.sort(list, comparator);
13765
13766         final long curRealtime = SystemClock.elapsedRealtime();
13767         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13768         final long curUptime = SystemClock.uptimeMillis();
13769         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13770
13771         for (int i=list.size()-1; i>=0; i--) {
13772             ProcessRecord r = list.get(i).first;
13773             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13774             char schedGroup;
13775             switch (r.setSchedGroup) {
13776                 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13777                     schedGroup = 'B';
13778                     break;
13779                 case Process.THREAD_GROUP_DEFAULT:
13780                     schedGroup = 'F';
13781                     break;
13782                 default:
13783                     schedGroup = '?';
13784                     break;
13785             }
13786             char foreground;
13787             if (r.foregroundActivities) {
13788                 foreground = 'A';
13789             } else if (r.foregroundServices) {
13790                 foreground = 'S';
13791             } else {
13792                 foreground = ' ';
13793             }
13794             String procState = ProcessList.makeProcStateString(r.curProcState);
13795             pw.print(prefix);
13796             pw.print(r.persistent ? persistentLabel : normalLabel);
13797             pw.print(" #");
13798             int num = (origList.size()-1)-list.get(i).second;
13799             if (num < 10) pw.print(' ');
13800             pw.print(num);
13801             pw.print(": ");
13802             pw.print(oomAdj);
13803             pw.print(' ');
13804             pw.print(schedGroup);
13805             pw.print('/');
13806             pw.print(foreground);
13807             pw.print('/');
13808             pw.print(procState);
13809             pw.print(" trm:");
13810             if (r.trimMemoryLevel < 10) pw.print(' ');
13811             pw.print(r.trimMemoryLevel);
13812             pw.print(' ');
13813             pw.print(r.toShortString());
13814             pw.print(" (");
13815             pw.print(r.adjType);
13816             pw.println(')');
13817             if (r.adjSource != null || r.adjTarget != null) {
13818                 pw.print(prefix);
13819                 pw.print("    ");
13820                 if (r.adjTarget instanceof ComponentName) {
13821                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13822                 } else if (r.adjTarget != null) {
13823                     pw.print(r.adjTarget.toString());
13824                 } else {
13825                     pw.print("{null}");
13826                 }
13827                 pw.print("<=");
13828                 if (r.adjSource instanceof ProcessRecord) {
13829                     pw.print("Proc{");
13830                     pw.print(((ProcessRecord)r.adjSource).toShortString());
13831                     pw.println("}");
13832                 } else if (r.adjSource != null) {
13833                     pw.println(r.adjSource.toString());
13834                 } else {
13835                     pw.println("{null}");
13836                 }
13837             }
13838             if (inclDetails) {
13839                 pw.print(prefix);
13840                 pw.print("    ");
13841                 pw.print("oom: max="); pw.print(r.maxAdj);
13842                 pw.print(" curRaw="); pw.print(r.curRawAdj);
13843                 pw.print(" setRaw="); pw.print(r.setRawAdj);
13844                 pw.print(" cur="); pw.print(r.curAdj);
13845                 pw.print(" set="); pw.println(r.setAdj);
13846                 pw.print(prefix);
13847                 pw.print("    ");
13848                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13849                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13850                 pw.print(" lastPss="); pw.print(r.lastPss);
13851                 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13852                 pw.print(prefix);
13853                 pw.print("    ");
13854                 pw.print("cached="); pw.print(r.cached);
13855                 pw.print(" empty="); pw.print(r.empty);
13856                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13857
13858                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13859                     if (r.lastWakeTime != 0) {
13860                         long wtime;
13861                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13862                         synchronized (stats) {
13863                             wtime = stats.getProcessWakeTime(r.info.uid,
13864                                     r.pid, curRealtime);
13865                         }
13866                         long timeUsed = wtime - r.lastWakeTime;
13867                         pw.print(prefix);
13868                         pw.print("    ");
13869                         pw.print("keep awake over ");
13870                         TimeUtils.formatDuration(realtimeSince, pw);
13871                         pw.print(" used ");
13872                         TimeUtils.formatDuration(timeUsed, pw);
13873                         pw.print(" (");
13874                         pw.print((timeUsed*100)/realtimeSince);
13875                         pw.println("%)");
13876                     }
13877                     if (r.lastCpuTime != 0) {
13878                         long timeUsed = r.curCpuTime - r.lastCpuTime;
13879                         pw.print(prefix);
13880                         pw.print("    ");
13881                         pw.print("run cpu over ");
13882                         TimeUtils.formatDuration(uptimeSince, pw);
13883                         pw.print(" used ");
13884                         TimeUtils.formatDuration(timeUsed, pw);
13885                         pw.print(" (");
13886                         pw.print((timeUsed*100)/uptimeSince);
13887                         pw.println("%)");
13888                     }
13889                 }
13890             }
13891         }
13892         return true;
13893     }
13894
13895     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13896             String[] args) {
13897         ArrayList<ProcessRecord> procs;
13898         synchronized (this) {
13899             if (args != null && args.length > start
13900                     && args[start].charAt(0) != '-') {
13901                 procs = new ArrayList<ProcessRecord>();
13902                 int pid = -1;
13903                 try {
13904                     pid = Integer.parseInt(args[start]);
13905                 } catch (NumberFormatException e) {
13906                 }
13907                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13908                     ProcessRecord proc = mLruProcesses.get(i);
13909                     if (proc.pid == pid) {
13910                         procs.add(proc);
13911                     } else if (allPkgs && proc.pkgList != null
13912                             && proc.pkgList.containsKey(args[start])) {
13913                         procs.add(proc);
13914                     } else if (proc.processName.equals(args[start])) {
13915                         procs.add(proc);
13916                     }
13917                 }
13918                 if (procs.size() <= 0) {
13919                     return null;
13920                 }
13921             } else {
13922                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13923             }
13924         }
13925         return procs;
13926     }
13927
13928     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13929             PrintWriter pw, String[] args) {
13930         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13931         if (procs == null) {
13932             pw.println("No process found for: " + args[0]);
13933             return;
13934         }
13935
13936         long uptime = SystemClock.uptimeMillis();
13937         long realtime = SystemClock.elapsedRealtime();
13938         pw.println("Applications Graphics Acceleration Info:");
13939         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13940         
13941         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13942             ProcessRecord r = procs.get(i);
13943             if (r.thread != null) {
13944                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13945                 pw.flush();
13946                 try {
13947                     TransferPipe tp = new TransferPipe();
13948                     try {
13949                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13950                         tp.go(fd);
13951                     } finally {
13952                         tp.kill();
13953                     }
13954                 } catch (IOException e) {
13955                     pw.println("Failure while dumping the app: " + r);
13956                     pw.flush();
13957                 } catch (RemoteException e) {
13958                     pw.println("Got a RemoteException while dumping the app " + r);
13959                     pw.flush();
13960                 }
13961             }
13962         }
13963     }
13964
13965     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13966         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13967         if (procs == null) {
13968             pw.println("No process found for: " + args[0]);
13969             return;
13970         }
13971
13972         pw.println("Applications Database Info:");
13973
13974         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13975             ProcessRecord r = procs.get(i);
13976             if (r.thread != null) {
13977                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13978                 pw.flush();
13979                 try {
13980                     TransferPipe tp = new TransferPipe();
13981                     try {
13982                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13983                         tp.go(fd);
13984                     } finally {
13985                         tp.kill();
13986                     }
13987                 } catch (IOException e) {
13988                     pw.println("Failure while dumping the app: " + r);
13989                     pw.flush();
13990                 } catch (RemoteException e) {
13991                     pw.println("Got a RemoteException while dumping the app " + r);
13992                     pw.flush();
13993                 }
13994             }
13995         }
13996     }
13997
13998     final static class MemItem {
13999         final boolean isProc;
14000         final String label;
14001         final String shortLabel;
14002         final long pss;
14003         final int id;
14004         final boolean hasActivities;
14005         ArrayList<MemItem> subitems;
14006
14007         public MemItem(String _label, String _shortLabel, long _pss, int _id,
14008                 boolean _hasActivities) {
14009             isProc = true;
14010             label = _label;
14011             shortLabel = _shortLabel;
14012             pss = _pss;
14013             id = _id;
14014             hasActivities = _hasActivities;
14015         }
14016
14017         public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14018             isProc = false;
14019             label = _label;
14020             shortLabel = _shortLabel;
14021             pss = _pss;
14022             id = _id;
14023             hasActivities = false;
14024         }
14025     }
14026
14027     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14028             ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14029         if (sort && !isCompact) {
14030             Collections.sort(items, new Comparator<MemItem>() {
14031                 @Override
14032                 public int compare(MemItem lhs, MemItem rhs) {
14033                     if (lhs.pss < rhs.pss) {
14034                         return 1;
14035                     } else if (lhs.pss > rhs.pss) {
14036                         return -1;
14037                     }
14038                     return 0;
14039                 }
14040             });
14041         }
14042
14043         for (int i=0; i<items.size(); i++) {
14044             MemItem mi = items.get(i);
14045             if (!isCompact) {
14046                 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14047             } else if (mi.isProc) {
14048                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14049                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14050                 pw.println(mi.hasActivities ? ",a" : ",e");
14051             } else {
14052                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14053                 pw.println(mi.pss);
14054             }
14055             if (mi.subitems != null) {
14056                 dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
14057                         true, isCompact);
14058             }
14059         }
14060     }
14061
14062     // These are in KB.
14063     static final long[] DUMP_MEM_BUCKETS = new long[] {
14064         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14065         120*1024, 160*1024, 200*1024,
14066         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14067         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14068     };
14069
14070     static final void appendMemBucket(StringBuilder out, long memKB, String label,
14071             boolean stackLike) {
14072         int start = label.lastIndexOf('.');
14073         if (start >= 0) start++;
14074         else start = 0;
14075         int end = label.length();
14076         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14077             if (DUMP_MEM_BUCKETS[i] >= memKB) {
14078                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14079                 out.append(bucket);
14080                 out.append(stackLike ? "MB." : "MB ");
14081                 out.append(label, start, end);
14082                 return;
14083             }
14084         }
14085         out.append(memKB/1024);
14086         out.append(stackLike ? "MB." : "MB ");
14087         out.append(label, start, end);
14088     }
14089
14090     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14091             ProcessList.NATIVE_ADJ,
14092             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14093             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14094             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14095             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14096             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14097             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14098     };
14099     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14100             "Native",
14101             "System", "Persistent", "Persistent Service", "Foreground",
14102             "Visible", "Perceptible",
14103             "Heavy Weight", "Backup",
14104             "A Services", "Home",
14105             "Previous", "B Services", "Cached"
14106     };
14107     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14108             "native",
14109             "sys", "pers", "persvc", "fore",
14110             "vis", "percept",
14111             "heavy", "backup",
14112             "servicea", "home",
14113             "prev", "serviceb", "cached"
14114     };
14115
14116     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14117             long realtime, boolean isCheckinRequest, boolean isCompact) {
14118         if (isCheckinRequest || isCompact) {
14119             // short checkin version
14120             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14121         } else {
14122             pw.println("Applications Memory Usage (kB):");
14123             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14124         }
14125     }
14126
14127     private static final int KSM_SHARED = 0;
14128     private static final int KSM_SHARING = 1;
14129     private static final int KSM_UNSHARED = 2;
14130     private static final int KSM_VOLATILE = 3;
14131
14132     private final long[] getKsmInfo() {
14133         long[] longOut = new long[4];
14134         final int[] SINGLE_LONG_FORMAT = new int[] {
14135             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14136         };
14137         long[] longTmp = new long[1];
14138         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14139                 SINGLE_LONG_FORMAT, null, longTmp, null);
14140         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14141         longTmp[0] = 0;
14142         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14143                 SINGLE_LONG_FORMAT, null, longTmp, null);
14144         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14145         longTmp[0] = 0;
14146         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14147                 SINGLE_LONG_FORMAT, null, longTmp, null);
14148         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14149         longTmp[0] = 0;
14150         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14151                 SINGLE_LONG_FORMAT, null, longTmp, null);
14152         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14153         return longOut;
14154     }
14155
14156     final void dumpApplicationMemoryUsage(FileDescriptor fd,
14157             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14158         boolean dumpDetails = false;
14159         boolean dumpFullDetails = false;
14160         boolean dumpDalvik = false;
14161         boolean oomOnly = false;
14162         boolean isCompact = false;
14163         boolean localOnly = false;
14164         boolean packages = false;
14165         
14166         int opti = 0;
14167         while (opti < args.length) {
14168             String opt = args[opti];
14169             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14170                 break;
14171             }
14172             opti++;
14173             if ("-a".equals(opt)) {
14174                 dumpDetails = true;
14175                 dumpFullDetails = true;
14176                 dumpDalvik = true;
14177             } else if ("-d".equals(opt)) {
14178                 dumpDalvik = true;
14179             } else if ("-c".equals(opt)) {
14180                 isCompact = true;
14181             } else if ("--oom".equals(opt)) {
14182                 oomOnly = true;
14183             } else if ("--local".equals(opt)) {
14184                 localOnly = true;
14185             } else if ("--package".equals(opt)) {
14186                 packages = true;
14187             } else if ("-h".equals(opt)) {
14188                 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14189                 pw.println("  -a: include all available information for each process.");
14190                 pw.println("  -d: include dalvik details when dumping process details.");
14191                 pw.println("  -c: dump in a compact machine-parseable representation.");
14192                 pw.println("  --oom: only show processes organized by oom adj.");
14193                 pw.println("  --local: only collect details locally, don't call process.");
14194                 pw.println("  --package: interpret process arg as package, dumping all");
14195                 pw.println("             processes that have loaded that package.");
14196                 pw.println("If [process] is specified it can be the name or ");
14197                 pw.println("pid of a specific process to dump.");
14198                 return;
14199             } else {
14200                 pw.println("Unknown argument: " + opt + "; use -h for help");
14201             }
14202         }
14203         
14204         final boolean isCheckinRequest = scanArgs(args, "--checkin");
14205         long uptime = SystemClock.uptimeMillis();
14206         long realtime = SystemClock.elapsedRealtime();
14207         final long[] tmpLong = new long[1];
14208
14209         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14210         if (procs == null) {
14211             // No Java processes.  Maybe they want to print a native process.
14212             if (args != null && args.length > opti
14213                     && args[opti].charAt(0) != '-') {
14214                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14215                         = new ArrayList<ProcessCpuTracker.Stats>();
14216                 updateCpuStatsNow();
14217                 int findPid = -1;
14218                 try {
14219                     findPid = Integer.parseInt(args[opti]);
14220                 } catch (NumberFormatException e) {
14221                 }
14222                 synchronized (mProcessCpuTracker) {
14223                     final int N = mProcessCpuTracker.countStats();
14224                     for (int i=0; i<N; i++) {
14225                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14226                         if (st.pid == findPid || (st.baseName != null
14227                                 && st.baseName.equals(args[opti]))) {
14228                             nativeProcs.add(st);
14229                         }
14230                     }
14231                 }
14232                 if (nativeProcs.size() > 0) {
14233                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14234                             isCompact);
14235                     Debug.MemoryInfo mi = null;
14236                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14237                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14238                         final int pid = r.pid;
14239                         if (!isCheckinRequest && dumpDetails) {
14240                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14241                         }
14242                         if (mi == null) {
14243                             mi = new Debug.MemoryInfo();
14244                         }
14245                         if (dumpDetails || (!brief && !oomOnly)) {
14246                             Debug.getMemoryInfo(pid, mi);
14247                         } else {
14248                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14249                             mi.dalvikPrivateDirty = (int)tmpLong[0];
14250                         }
14251                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14252                                 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14253                         if (isCheckinRequest) {
14254                             pw.println();
14255                         }
14256                     }
14257                     return;
14258                 }
14259             }
14260             pw.println("No process found for: " + args[opti]);
14261             return;
14262         }
14263
14264         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14265             dumpDetails = true;
14266         }
14267
14268         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14269
14270         String[] innerArgs = new String[args.length-opti];
14271         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14272
14273         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14274         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14275         long nativePss = 0;
14276         long dalvikPss = 0;
14277         long otherPss = 0;
14278         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14279
14280         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14281         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14282                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14283
14284         long totalPss = 0;
14285         long cachedPss = 0;
14286
14287         Debug.MemoryInfo mi = null;
14288         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14289             final ProcessRecord r = procs.get(i);
14290             final IApplicationThread thread;
14291             final int pid;
14292             final int oomAdj;
14293             final boolean hasActivities;
14294             synchronized (this) {
14295                 thread = r.thread;
14296                 pid = r.pid;
14297                 oomAdj = r.getSetAdjWithServices();
14298                 hasActivities = r.activities.size() > 0;
14299             }
14300             if (thread != null) {
14301                 if (!isCheckinRequest && dumpDetails) {
14302                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14303                 }
14304                 if (mi == null) {
14305                     mi = new Debug.MemoryInfo();
14306                 }
14307                 if (dumpDetails || (!brief && !oomOnly)) {
14308                     Debug.getMemoryInfo(pid, mi);
14309                 } else {
14310                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14311                     mi.dalvikPrivateDirty = (int)tmpLong[0];
14312                 }
14313                 if (dumpDetails) {
14314                     if (localOnly) {
14315                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14316                                 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14317                         if (isCheckinRequest) {
14318                             pw.println();
14319                         }
14320                     } else {
14321                         try {
14322                             pw.flush();
14323                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14324                                     dumpDalvik, innerArgs);
14325                         } catch (RemoteException e) {
14326                             if (!isCheckinRequest) {
14327                                 pw.println("Got RemoteException!");
14328                                 pw.flush();
14329                             }
14330                         }
14331                     }
14332                 }
14333
14334                 final long myTotalPss = mi.getTotalPss();
14335                 final long myTotalUss = mi.getTotalUss();
14336
14337                 synchronized (this) {
14338                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14339                         // Record this for posterity if the process has been stable.
14340                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14341                     }
14342                 }
14343
14344                 if (!isCheckinRequest && mi != null) {
14345                     totalPss += myTotalPss;
14346                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14347                             (hasActivities ? " / activities)" : ")"),
14348                             r.processName, myTotalPss, pid, hasActivities);
14349                     procMems.add(pssItem);
14350                     procMemsMap.put(pid, pssItem);
14351
14352                     nativePss += mi.nativePss;
14353                     dalvikPss += mi.dalvikPss;
14354                     otherPss += mi.otherPss;
14355                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14356                         long mem = mi.getOtherPss(j);
14357                         miscPss[j] += mem;
14358                         otherPss -= mem;
14359                     }
14360
14361                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14362                         cachedPss += myTotalPss;
14363                     }
14364
14365                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14366                         if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14367                                 || oomIndex == (oomPss.length-1)) {
14368                             oomPss[oomIndex] += myTotalPss;
14369                             if (oomProcs[oomIndex] == null) {
14370                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
14371                             }
14372                             oomProcs[oomIndex].add(pssItem);
14373                             break;
14374                         }
14375                     }
14376                 }
14377             }
14378         }
14379
14380         long nativeProcTotalPss = 0;
14381
14382         if (!isCheckinRequest && procs.size() > 1 && !packages) {
14383             // If we are showing aggregations, also look for native processes to
14384             // include so that our aggregations are more accurate.
14385             updateCpuStatsNow();
14386             mi = null;
14387             synchronized (mProcessCpuTracker) {
14388                 final int N = mProcessCpuTracker.countStats();
14389                 for (int i=0; i<N; i++) {
14390                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14391                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14392                         if (mi == null) {
14393                             mi = new Debug.MemoryInfo();
14394                         }
14395                         if (!brief && !oomOnly) {
14396                             Debug.getMemoryInfo(st.pid, mi);
14397                         } else {
14398                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14399                             mi.nativePrivateDirty = (int)tmpLong[0];
14400                         }
14401
14402                         final long myTotalPss = mi.getTotalPss();
14403                         totalPss += myTotalPss;
14404                         nativeProcTotalPss += myTotalPss;
14405
14406                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14407                                 st.name, myTotalPss, st.pid, false);
14408                         procMems.add(pssItem);
14409
14410                         nativePss += mi.nativePss;
14411                         dalvikPss += mi.dalvikPss;
14412                         otherPss += mi.otherPss;
14413                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14414                             long mem = mi.getOtherPss(j);
14415                             miscPss[j] += mem;
14416                             otherPss -= mem;
14417                         }
14418                         oomPss[0] += myTotalPss;
14419                         if (oomProcs[0] == null) {
14420                             oomProcs[0] = new ArrayList<MemItem>();
14421                         }
14422                         oomProcs[0].add(pssItem);
14423                     }
14424                 }
14425             }
14426
14427             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14428
14429             catMems.add(new MemItem("Native", "Native", nativePss, -1));
14430             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14431             catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14432             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14433                 String label = Debug.MemoryInfo.getOtherLabel(j);
14434                 catMems.add(new MemItem(label, label, miscPss[j], j));
14435             }
14436
14437             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14438             for (int j=0; j<oomPss.length; j++) {
14439                 if (oomPss[j] != 0) {
14440                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14441                             : DUMP_MEM_OOM_LABEL[j];
14442                     MemItem item = new MemItem(label, label, oomPss[j],
14443                             DUMP_MEM_OOM_ADJ[j]);
14444                     item.subitems = oomProcs[j];
14445                     oomMems.add(item);
14446                 }
14447             }
14448
14449             if (!brief && !oomOnly && !isCompact) {
14450                 pw.println();
14451                 pw.println("Total PSS by process:");
14452                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14453                 pw.println();
14454             }
14455             if (!isCompact) {
14456                 pw.println("Total PSS by OOM adjustment:");
14457             }
14458             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14459             if (!brief && !oomOnly) {
14460                 PrintWriter out = categoryPw != null ? categoryPw : pw;
14461                 if (!isCompact) {
14462                     out.println();
14463                     out.println("Total PSS by category:");
14464                 }
14465                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14466             }
14467             if (!isCompact) {
14468                 pw.println();
14469             }
14470             MemInfoReader memInfo = new MemInfoReader();
14471             memInfo.readMemInfo();
14472             if (nativeProcTotalPss > 0) {
14473                 synchronized (this) {
14474                     mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14475                             memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14476                             memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14477                 }
14478             }
14479             if (!brief) {
14480                 if (!isCompact) {
14481                     pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14482                     pw.print(" kB (status ");
14483                     switch (mLastMemoryLevel) {
14484                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14485                             pw.println("normal)");
14486                             break;
14487                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14488                             pw.println("moderate)");
14489                             break;
14490                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
14491                             pw.println("low)");
14492                             break;
14493                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14494                             pw.println("critical)");
14495                             break;
14496                         default:
14497                             pw.print(mLastMemoryLevel);
14498                             pw.println(")");
14499                             break;
14500                     }
14501                     pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14502                             + memInfo.getFreeSizeKb()); pw.print(" kB (");
14503                             pw.print(cachedPss); pw.print(" cached pss + ");
14504                             pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14505                             pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14506                 } else {
14507                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14508                     pw.print(cachedPss + memInfo.getCachedSizeKb()
14509                             + memInfo.getFreeSizeKb()); pw.print(",");
14510                     pw.println(totalPss - cachedPss);
14511                 }
14512             }
14513             if (!isCompact) {
14514                 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14515                         + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14516                         pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14517                         pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14518                 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14519                         - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14520                         - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14521             }
14522             if (!brief) {
14523                 if (memInfo.getZramTotalSizeKb() != 0) {
14524                     if (!isCompact) {
14525                         pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14526                                 pw.print(" kB physical used for ");
14527                                 pw.print(memInfo.getSwapTotalSizeKb()
14528                                         - memInfo.getSwapFreeSizeKb());
14529                                 pw.print(" kB in swap (");
14530                                 pw.print(memInfo.getSwapTotalSizeKb());
14531                                 pw.println(" kB total swap)");
14532                     } else {
14533                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14534                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14535                                 pw.println(memInfo.getSwapFreeSizeKb());
14536                     }
14537                 }
14538                 final long[] ksm = getKsmInfo();
14539                 if (!isCompact) {
14540                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14541                             || ksm[KSM_VOLATILE] != 0) {
14542                         pw.print("      KSM: "); pw.print(ksm[KSM_SHARING]);
14543                                 pw.print(" kB saved from shared ");
14544                                 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14545                         pw.print("           "); pw.print(ksm[KSM_UNSHARED]);
14546                                 pw.print(" kB unshared; ");
14547                                 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14548                     }
14549                     pw.print("   Tuning: ");
14550                     pw.print(ActivityManager.staticGetMemoryClass());
14551                     pw.print(" (large ");
14552                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14553                     pw.print("), oom ");
14554                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14555                     pw.print(" kB");
14556                     pw.print(", restore limit ");
14557                     pw.print(mProcessList.getCachedRestoreThresholdKb());
14558                     pw.print(" kB");
14559                     if (ActivityManager.isLowRamDeviceStatic()) {
14560                         pw.print(" (low-ram)");
14561                     }
14562                     if (ActivityManager.isHighEndGfx()) {
14563                         pw.print(" (high-end-gfx)");
14564                     }
14565                     pw.println();
14566                 } else {
14567                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14568                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14569                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14570                     pw.print("tuning,");
14571                     pw.print(ActivityManager.staticGetMemoryClass());
14572                     pw.print(',');
14573                     pw.print(ActivityManager.staticGetLargeMemoryClass());
14574                     pw.print(',');
14575                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14576                     if (ActivityManager.isLowRamDeviceStatic()) {
14577                         pw.print(",low-ram");
14578                     }
14579                     if (ActivityManager.isHighEndGfx()) {
14580                         pw.print(",high-end-gfx");
14581                     }
14582                     pw.println();
14583                 }
14584             }
14585         }
14586     }
14587
14588     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14589             long memtrack, String name) {
14590         sb.append("  ");
14591         sb.append(ProcessList.makeOomAdjString(oomAdj));
14592         sb.append(' ');
14593         sb.append(ProcessList.makeProcStateString(procState));
14594         sb.append(' ');
14595         ProcessList.appendRamKb(sb, pss);
14596         sb.append(" kB: ");
14597         sb.append(name);
14598         if (memtrack > 0) {
14599             sb.append(" (");
14600             sb.append(memtrack);
14601             sb.append(" kB memtrack)");
14602         }
14603     }
14604
14605     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14606         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14607         sb.append(" (pid ");
14608         sb.append(mi.pid);
14609         sb.append(") ");
14610         sb.append(mi.adjType);
14611         sb.append('\n');
14612         if (mi.adjReason != null) {
14613             sb.append("                      ");
14614             sb.append(mi.adjReason);
14615             sb.append('\n');
14616         }
14617     }
14618
14619     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14620         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14621         for (int i=0, N=memInfos.size(); i<N; i++) {
14622             ProcessMemInfo mi = memInfos.get(i);
14623             infoMap.put(mi.pid, mi);
14624         }
14625         updateCpuStatsNow();
14626         long[] memtrackTmp = new long[1];
14627         synchronized (mProcessCpuTracker) {
14628             final int N = mProcessCpuTracker.countStats();
14629             for (int i=0; i<N; i++) {
14630                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14631                 if (st.vsize > 0) {
14632                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
14633                     if (pss > 0) {
14634                         if (infoMap.indexOfKey(st.pid) < 0) {
14635                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14636                                     ProcessList.NATIVE_ADJ, -1, "native", null);
14637                             mi.pss = pss;
14638                             mi.memtrack = memtrackTmp[0];
14639                             memInfos.add(mi);
14640                         }
14641                     }
14642                 }
14643             }
14644         }
14645
14646         long totalPss = 0;
14647         long totalMemtrack = 0;
14648         for (int i=0, N=memInfos.size(); i<N; i++) {
14649             ProcessMemInfo mi = memInfos.get(i);
14650             if (mi.pss == 0) {
14651                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14652                 mi.memtrack = memtrackTmp[0];
14653             }
14654             totalPss += mi.pss;
14655             totalMemtrack += mi.memtrack;
14656         }
14657         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14658             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14659                 if (lhs.oomAdj != rhs.oomAdj) {
14660                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14661                 }
14662                 if (lhs.pss != rhs.pss) {
14663                     return lhs.pss < rhs.pss ? 1 : -1;
14664                 }
14665                 return 0;
14666             }
14667         });
14668
14669         StringBuilder tag = new StringBuilder(128);
14670         StringBuilder stack = new StringBuilder(128);
14671         tag.append("Low on memory -- ");
14672         appendMemBucket(tag, totalPss, "total", false);
14673         appendMemBucket(stack, totalPss, "total", true);
14674
14675         StringBuilder fullNativeBuilder = new StringBuilder(1024);
14676         StringBuilder shortNativeBuilder = new StringBuilder(1024);
14677         StringBuilder fullJavaBuilder = new StringBuilder(1024);
14678
14679         boolean firstLine = true;
14680         int lastOomAdj = Integer.MIN_VALUE;
14681         long extraNativeRam = 0;
14682         long extraNativeMemtrack = 0;
14683         long cachedPss = 0;
14684         for (int i=0, N=memInfos.size(); i<N; i++) {
14685             ProcessMemInfo mi = memInfos.get(i);
14686
14687             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14688                 cachedPss += mi.pss;
14689             }
14690
14691             if (mi.oomAdj != ProcessList.NATIVE_ADJ
14692                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
14693                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
14694                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14695                 if (lastOomAdj != mi.oomAdj) {
14696                     lastOomAdj = mi.oomAdj;
14697                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14698                         tag.append(" / ");
14699                     }
14700                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14701                         if (firstLine) {
14702                             stack.append(":");
14703                             firstLine = false;
14704                         }
14705                         stack.append("\n\t at ");
14706                     } else {
14707                         stack.append("$");
14708                     }
14709                 } else {
14710                     tag.append(" ");
14711                     stack.append("$");
14712                 }
14713                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14714                     appendMemBucket(tag, mi.pss, mi.name, false);
14715                 }
14716                 appendMemBucket(stack, mi.pss, mi.name, true);
14717                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14718                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14719                     stack.append("(");
14720                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14721                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14722                             stack.append(DUMP_MEM_OOM_LABEL[k]);
14723                             stack.append(":");
14724                             stack.append(DUMP_MEM_OOM_ADJ[k]);
14725                         }
14726                     }
14727                     stack.append(")");
14728                 }
14729             }
14730
14731             appendMemInfo(fullNativeBuilder, mi);
14732             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14733                 // The short form only has native processes that are >= 512K.
14734                 if (mi.pss >= 512) {
14735                     appendMemInfo(shortNativeBuilder, mi);
14736                 } else {
14737                     extraNativeRam += mi.pss;
14738                     extraNativeMemtrack += mi.memtrack;
14739                 }
14740             } else {
14741                 // Short form has all other details, but if we have collected RAM
14742                 // from smaller native processes let's dump a summary of that.
14743                 if (extraNativeRam > 0) {
14744                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14745                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14746                     shortNativeBuilder.append('\n');
14747                     extraNativeRam = 0;
14748                 }
14749                 appendMemInfo(fullJavaBuilder, mi);
14750             }
14751         }
14752
14753         fullJavaBuilder.append("           ");
14754         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14755         fullJavaBuilder.append(" kB: TOTAL");
14756         if (totalMemtrack > 0) {
14757             fullJavaBuilder.append(" (");
14758             fullJavaBuilder.append(totalMemtrack);
14759             fullJavaBuilder.append(" kB memtrack)");
14760         } else {
14761         }
14762         fullJavaBuilder.append("\n");
14763
14764         MemInfoReader memInfo = new MemInfoReader();
14765         memInfo.readMemInfo();
14766         final long[] infos = memInfo.getRawInfo();
14767
14768         StringBuilder memInfoBuilder = new StringBuilder(1024);
14769         Debug.getMemInfo(infos);
14770         memInfoBuilder.append("  MemInfo: ");
14771         memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14772         memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14773         memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14774         memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14775         memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14776         memInfoBuilder.append("           ");
14777         memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14778         memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14779         memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14780         memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14781         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14782             memInfoBuilder.append("  ZRAM: ");
14783             memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14784             memInfoBuilder.append(" kB RAM, ");
14785             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14786             memInfoBuilder.append(" kB swap total, ");
14787             memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14788             memInfoBuilder.append(" kB swap free\n");
14789         }
14790         final long[] ksm = getKsmInfo();
14791         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14792                 || ksm[KSM_VOLATILE] != 0) {
14793             memInfoBuilder.append("  KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14794             memInfoBuilder.append(" kB saved from shared ");
14795             memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14796             memInfoBuilder.append("       "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14797             memInfoBuilder.append(" kB unshared; ");
14798             memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14799         }
14800         memInfoBuilder.append("  Free RAM: ");
14801         memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14802                 + memInfo.getFreeSizeKb());
14803         memInfoBuilder.append(" kB\n");
14804         memInfoBuilder.append("  Used RAM: ");
14805         memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14806         memInfoBuilder.append(" kB\n");
14807         memInfoBuilder.append("  Lost RAM: ");
14808         memInfoBuilder.append(memInfo.getTotalSizeKb()
14809                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14810                 - memInfo.getKernelUsedSizeKb());
14811         memInfoBuilder.append(" kB\n");
14812         Slog.i(TAG, "Low on memory:");
14813         Slog.i(TAG, shortNativeBuilder.toString());
14814         Slog.i(TAG, fullJavaBuilder.toString());
14815         Slog.i(TAG, memInfoBuilder.toString());
14816
14817         StringBuilder dropBuilder = new StringBuilder(1024);
14818         /*
14819         StringWriter oomSw = new StringWriter();
14820         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14821         StringWriter catSw = new StringWriter();
14822         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14823         String[] emptyArgs = new String[] { };
14824         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
14825         oomPw.flush();
14826         String oomString = oomSw.toString();
14827         */
14828         dropBuilder.append("Low on memory:");
14829         dropBuilder.append(stack);
14830         dropBuilder.append('\n');
14831         dropBuilder.append(fullNativeBuilder);
14832         dropBuilder.append(fullJavaBuilder);
14833         dropBuilder.append('\n');
14834         dropBuilder.append(memInfoBuilder);
14835         dropBuilder.append('\n');
14836         /*
14837         dropBuilder.append(oomString);
14838         dropBuilder.append('\n');
14839         */
14840         StringWriter catSw = new StringWriter();
14841         synchronized (ActivityManagerService.this) {
14842             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14843             String[] emptyArgs = new String[] { };
14844             catPw.println();
14845             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14846             catPw.println();
14847             mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14848                     false, false, null);
14849             catPw.println();
14850             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14851             catPw.flush();
14852         }
14853         dropBuilder.append(catSw.toString());
14854         addErrorToDropBox("lowmem", null, "system_server", null,
14855                 null, tag.toString(), dropBuilder.toString(), null, null);
14856         //Slog.i(TAG, "Sent to dropbox:");
14857         //Slog.i(TAG, dropBuilder.toString());
14858         synchronized (ActivityManagerService.this) {
14859             long now = SystemClock.uptimeMillis();
14860             if (mLastMemUsageReportTime < now) {
14861                 mLastMemUsageReportTime = now;
14862             }
14863         }
14864     }
14865
14866     /**
14867      * Searches array of arguments for the specified string
14868      * @param args array of argument strings
14869      * @param value value to search for
14870      * @return true if the value is contained in the array
14871      */
14872     private static boolean scanArgs(String[] args, String value) {
14873         if (args != null) {
14874             for (String arg : args) {
14875                 if (value.equals(arg)) {
14876                     return true;
14877                 }
14878             }
14879         }
14880         return false;
14881     }
14882
14883     private final boolean removeDyingProviderLocked(ProcessRecord proc,
14884             ContentProviderRecord cpr, boolean always) {
14885         final boolean inLaunching = mLaunchingProviders.contains(cpr);
14886
14887         if (!inLaunching || always) {
14888             synchronized (cpr) {
14889                 cpr.launchingApp = null;
14890                 cpr.notifyAll();
14891             }
14892             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14893             String names[] = cpr.info.authority.split(";");
14894             for (int j = 0; j < names.length; j++) {
14895                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14896             }
14897         }
14898
14899         for (int i=0; i<cpr.connections.size(); i++) {
14900             ContentProviderConnection conn = cpr.connections.get(i);
14901             if (conn.waiting) {
14902                 // If this connection is waiting for the provider, then we don't
14903                 // need to mess with its process unless we are always removing
14904                 // or for some reason the provider is not currently launching.
14905                 if (inLaunching && !always) {
14906                     continue;
14907                 }
14908             }
14909             ProcessRecord capp = conn.client;
14910             conn.dead = true;
14911             if (conn.stableCount > 0) {
14912                 if (!capp.persistent && capp.thread != null
14913                         && capp.pid != 0
14914                         && capp.pid != MY_PID) {
14915                     capp.kill("depends on provider "
14916                             + cpr.name.flattenToShortString()
14917                             + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14918                 }
14919             } else if (capp.thread != null && conn.provider.provider != null) {
14920                 try {
14921                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14922                 } catch (RemoteException e) {
14923                 }
14924                 // In the protocol here, we don't expect the client to correctly
14925                 // clean up this connection, we'll just remove it.
14926                 cpr.connections.remove(i);
14927                 if (conn.client.conProviders.remove(conn)) {
14928                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14929                 }
14930             }
14931         }
14932
14933         if (inLaunching && always) {
14934             mLaunchingProviders.remove(cpr);
14935         }
14936         return inLaunching;
14937     }
14938
14939     /**
14940      * Main code for cleaning up a process when it has gone away.  This is
14941      * called both as a result of the process dying, or directly when stopping
14942      * a process when running in single process mode.
14943      *
14944      * @return Returns true if the given process has been restarted, so the
14945      * app that was passed in must remain on the process lists.
14946      */
14947     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14948             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
14949         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
14950         if (index >= 0) {
14951             removeLruProcessLocked(app);
14952             ProcessList.remove(app.pid);
14953         }
14954
14955         mProcessesToGc.remove(app);
14956         mPendingPssProcesses.remove(app);
14957
14958         // Dismiss any open dialogs.
14959         if (app.crashDialog != null && !app.forceCrashReport) {
14960             app.crashDialog.dismiss();
14961             app.crashDialog = null;
14962         }
14963         if (app.anrDialog != null) {
14964             app.anrDialog.dismiss();
14965             app.anrDialog = null;
14966         }
14967         if (app.waitDialog != null) {
14968             app.waitDialog.dismiss();
14969             app.waitDialog = null;
14970         }
14971
14972         app.crashing = false;
14973         app.notResponding = false;
14974
14975         app.resetPackageList(mProcessStats);
14976         app.unlinkDeathRecipient();
14977         app.makeInactive(mProcessStats);
14978         app.waitingToKill = null;
14979         app.forcingToForeground = null;
14980         updateProcessForegroundLocked(app, false, false);
14981         app.foregroundActivities = false;
14982         app.hasShownUi = false;
14983         app.treatLikeActivity = false;
14984         app.hasAboveClient = false;
14985         app.hasClientActivities = false;
14986
14987         mServices.killServicesLocked(app, allowRestart);
14988
14989         boolean restart = false;
14990
14991         // Remove published content providers.
14992         for (int i=app.pubProviders.size()-1; i>=0; i--) {
14993             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14994             final boolean always = app.bad || !allowRestart;
14995             if (removeDyingProviderLocked(app, cpr, always) || always) {
14996                 // We left the provider in the launching list, need to
14997                 // restart it.
14998                 restart = true;
14999             }
15000
15001             cpr.provider = null;
15002             cpr.proc = null;
15003         }
15004         app.pubProviders.clear();
15005
15006         // Take care of any launching providers waiting for this process.
15007         if (checkAppInLaunchingProvidersLocked(app, false)) {
15008             restart = true;
15009         }
15010
15011         // Unregister from connected content providers.
15012         if (!app.conProviders.isEmpty()) {
15013             for (int i=0; i<app.conProviders.size(); i++) {
15014                 ContentProviderConnection conn = app.conProviders.get(i);
15015                 conn.provider.connections.remove(conn);
15016                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15017                         conn.provider.name);
15018             }
15019             app.conProviders.clear();
15020         }
15021
15022         // At this point there may be remaining entries in mLaunchingProviders
15023         // where we were the only one waiting, so they are no longer of use.
15024         // Look for these and clean up if found.
15025         // XXX Commented out for now.  Trying to figure out a way to reproduce
15026         // the actual situation to identify what is actually going on.
15027         if (false) {
15028             for (int i=0; i<mLaunchingProviders.size(); i++) {
15029                 ContentProviderRecord cpr = (ContentProviderRecord)
15030                         mLaunchingProviders.get(i);
15031                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15032                     synchronized (cpr) {
15033                         cpr.launchingApp = null;
15034                         cpr.notifyAll();
15035                     }
15036                 }
15037             }
15038         }
15039
15040         skipCurrentReceiverLocked(app);
15041
15042         // Unregister any receivers.
15043         for (int i=app.receivers.size()-1; i>=0; i--) {
15044             removeReceiverLocked(app.receivers.valueAt(i));
15045         }
15046         app.receivers.clear();
15047
15048         // If the app is undergoing backup, tell the backup manager about it
15049         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15050             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
15051                     + mBackupTarget.appInfo + " died during backup");
15052             try {
15053                 IBackupManager bm = IBackupManager.Stub.asInterface(
15054                         ServiceManager.getService(Context.BACKUP_SERVICE));
15055                 bm.agentDisconnected(app.info.packageName);
15056             } catch (RemoteException e) {
15057                 // can't happen; backup manager is local
15058             }
15059         }
15060
15061         for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
15062             ProcessChangeItem item = mPendingProcessChanges.get(i);
15063             if (item.pid == app.pid) {
15064                 mPendingProcessChanges.remove(i);
15065                 mAvailProcessChanges.add(item);
15066             }
15067         }
15068         mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15069
15070         // If the caller is restarting this app, then leave it in its
15071         // current lists and let the caller take care of it.
15072         if (restarting) {
15073             return false;
15074         }
15075
15076         if (!app.persistent || app.isolated) {
15077             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15078                     "Removing non-persistent process during cleanup: " + app);
15079             if (!replacingPid) {
15080                 mProcessNames.remove(app.processName, app.uid);
15081                 mIsolatedProcesses.remove(app.uid);
15082             }
15083             if (mHeavyWeightProcess == app) {
15084                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15085                         mHeavyWeightProcess.userId, 0));
15086                 mHeavyWeightProcess = null;
15087             }
15088         } else if (!app.removed) {
15089             // This app is persistent, so we need to keep its record around.
15090             // If it is not already on the pending app list, add it there
15091             // and start a new process for it.
15092             if (mPersistentStartingProcesses.indexOf(app) < 0) {
15093                 mPersistentStartingProcesses.add(app);
15094                 restart = true;
15095             }
15096         }
15097         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15098                 "Clean-up removing on hold: " + app);
15099         mProcessesOnHold.remove(app);
15100
15101         if (app == mHomeProcess) {
15102             mHomeProcess = null;
15103         }
15104         if (app == mPreviousProcess) {
15105             mPreviousProcess = null;
15106         }
15107
15108         if (restart && !app.isolated) {
15109             // We have components that still need to be running in the
15110             // process, so re-launch it.
15111             if (index < 0) {
15112                 ProcessList.remove(app.pid);
15113             }
15114             mProcessNames.put(app.processName, app.uid, app);
15115             startProcessLocked(app, "restart", app.processName);
15116             return true;
15117         } else if (app.pid > 0 && app.pid != MY_PID) {
15118             // Goodbye!
15119             boolean removed;
15120             synchronized (mPidsSelfLocked) {
15121                 mPidsSelfLocked.remove(app.pid);
15122                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15123             }
15124             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15125             if (app.isolated) {
15126                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15127             }
15128             app.setPid(0);
15129         }
15130         return false;
15131     }
15132
15133     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15134         // Look through the content providers we are waiting to have launched,
15135         // and if any run in this process then either schedule a restart of
15136         // the process or kill the client waiting for it if this process has
15137         // gone bad.
15138         int NL = mLaunchingProviders.size();
15139         boolean restart = false;
15140         for (int i=0; i<NL; i++) {
15141             ContentProviderRecord cpr = mLaunchingProviders.get(i);
15142             if (cpr.launchingApp == app) {
15143                 if (!alwaysBad && !app.bad) {
15144                     restart = true;
15145                 } else {
15146                     removeDyingProviderLocked(app, cpr, true);
15147                     // cpr should have been removed from mLaunchingProviders
15148                     NL = mLaunchingProviders.size();
15149                     i--;
15150                 }
15151             }
15152         }
15153         return restart;
15154     }
15155     
15156     // =========================================================
15157     // SERVICES
15158     // =========================================================
15159
15160     @Override
15161     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15162             int flags) {
15163         enforceNotIsolatedCaller("getServices");
15164         synchronized (this) {
15165             return mServices.getRunningServiceInfoLocked(maxNum, flags);
15166         }
15167     }
15168
15169     @Override
15170     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15171         enforceNotIsolatedCaller("getRunningServiceControlPanel");
15172         synchronized (this) {
15173             return mServices.getRunningServiceControlPanelLocked(name);
15174         }
15175     }
15176
15177     @Override
15178     public ComponentName startService(IApplicationThread caller, Intent service,
15179             String resolvedType, int userId) {
15180         enforceNotIsolatedCaller("startService");
15181         // Refuse possible leaked file descriptors
15182         if (service != null && service.hasFileDescriptors() == true) {
15183             throw new IllegalArgumentException("File descriptors passed in Intent");
15184         }
15185
15186         if (DEBUG_SERVICE)
15187             Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15188         synchronized(this) {
15189             final int callingPid = Binder.getCallingPid();
15190             final int callingUid = Binder.getCallingUid();
15191             final long origId = Binder.clearCallingIdentity();
15192             ComponentName res = mServices.startServiceLocked(caller, service,
15193                     resolvedType, callingPid, callingUid, userId);
15194             Binder.restoreCallingIdentity(origId);
15195             return res;
15196         }
15197     }
15198
15199     ComponentName startServiceInPackage(int uid,
15200             Intent service, String resolvedType, int userId) {
15201         synchronized(this) {
15202             if (DEBUG_SERVICE)
15203                 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15204             final long origId = Binder.clearCallingIdentity();
15205             ComponentName res = mServices.startServiceLocked(null, service,
15206                     resolvedType, -1, uid, userId);
15207             Binder.restoreCallingIdentity(origId);
15208             return res;
15209         }
15210     }
15211
15212     @Override
15213     public int stopService(IApplicationThread caller, Intent service,
15214             String resolvedType, int userId) {
15215         enforceNotIsolatedCaller("stopService");
15216         // Refuse possible leaked file descriptors
15217         if (service != null && service.hasFileDescriptors() == true) {
15218             throw new IllegalArgumentException("File descriptors passed in Intent");
15219         }
15220
15221         synchronized(this) {
15222             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15223         }
15224     }
15225
15226     @Override
15227     public IBinder peekService(Intent service, String resolvedType) {
15228         enforceNotIsolatedCaller("peekService");
15229         // Refuse possible leaked file descriptors
15230         if (service != null && service.hasFileDescriptors() == true) {
15231             throw new IllegalArgumentException("File descriptors passed in Intent");
15232         }
15233         synchronized(this) {
15234             return mServices.peekServiceLocked(service, resolvedType);
15235         }
15236     }
15237     
15238     @Override
15239     public boolean stopServiceToken(ComponentName className, IBinder token,
15240             int startId) {
15241         synchronized(this) {
15242             return mServices.stopServiceTokenLocked(className, token, startId);
15243         }
15244     }
15245
15246     @Override
15247     public void setServiceForeground(ComponentName className, IBinder token,
15248             int id, Notification notification, boolean removeNotification) {
15249         synchronized(this) {
15250             mServices.setServiceForegroundLocked(className, token, id, notification,
15251                     removeNotification);
15252         }
15253     }
15254
15255     @Override
15256     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15257             boolean requireFull, String name, String callerPackage) {
15258         return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15259                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15260     }
15261
15262     int unsafeConvertIncomingUser(int userId) {
15263         return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15264                 ? mCurrentUserId : userId;
15265     }
15266
15267     int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15268             int allowMode, String name, String callerPackage) {
15269         final int callingUserId = UserHandle.getUserId(callingUid);
15270         if (callingUserId == userId) {
15271             return userId;
15272         }
15273
15274         // Note that we may be accessing mCurrentUserId outside of a lock...
15275         // shouldn't be a big deal, if this is being called outside
15276         // of a locked context there is intrinsically a race with
15277         // the value the caller will receive and someone else changing it.
15278         // We assume that USER_CURRENT_OR_SELF will use the current user; later
15279         // we will switch to the calling user if access to the current user fails.
15280         int targetUserId = unsafeConvertIncomingUser(userId);
15281
15282         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15283             final boolean allow;
15284             if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15285                     callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15286                 // If the caller has this permission, they always pass go.  And collect $200.
15287                 allow = true;
15288             } else if (allowMode == ALLOW_FULL_ONLY) {
15289                 // We require full access, sucks to be you.
15290                 allow = false;
15291             } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15292                     callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15293                 // If the caller does not have either permission, they are always doomed.
15294                 allow = false;
15295             } else if (allowMode == ALLOW_NON_FULL) {
15296                 // We are blanket allowing non-full access, you lucky caller!
15297                 allow = true;
15298             } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15299                 // We may or may not allow this depending on whether the two users are
15300                 // in the same profile.
15301                 synchronized (mUserProfileGroupIdsSelfLocked) {
15302                     int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15303                             UserInfo.NO_PROFILE_GROUP_ID);
15304                     int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15305                             UserInfo.NO_PROFILE_GROUP_ID);
15306                     allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15307                             && callingProfile == targetProfile;
15308                 }
15309             } else {
15310                 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15311             }
15312             if (!allow) {
15313                 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15314                     // In this case, they would like to just execute as their
15315                     // owner user instead of failing.
15316                     targetUserId = callingUserId;
15317                 } else {
15318                     StringBuilder builder = new StringBuilder(128);
15319                     builder.append("Permission Denial: ");
15320                     builder.append(name);
15321                     if (callerPackage != null) {
15322                         builder.append(" from ");
15323                         builder.append(callerPackage);
15324                     }
15325                     builder.append(" asks to run as user ");
15326                     builder.append(userId);
15327                     builder.append(" but is calling from user ");
15328                     builder.append(UserHandle.getUserId(callingUid));
15329                     builder.append("; this requires ");
15330                     builder.append(INTERACT_ACROSS_USERS_FULL);
15331                     if (allowMode != ALLOW_FULL_ONLY) {
15332                         builder.append(" or ");
15333                         builder.append(INTERACT_ACROSS_USERS);
15334                     }
15335                     String msg = builder.toString();
15336                     Slog.w(TAG, msg);
15337                     throw new SecurityException(msg);
15338                 }
15339             }
15340         }
15341         if (!allowAll && targetUserId < 0) {
15342             throw new IllegalArgumentException(
15343                     "Call does not support special user #" + targetUserId);
15344         }
15345         // Check shell permission
15346         if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15347             if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15348                     targetUserId)) {
15349                 throw new SecurityException("Shell does not have permission to access user "
15350                         + targetUserId + "\n " + Debug.getCallers(3));
15351             }
15352         }
15353         return targetUserId;
15354     }
15355
15356     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15357             String className, int flags) {
15358         boolean result = false;
15359         // For apps that don't have pre-defined UIDs, check for permission
15360         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15361             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15362                 if (ActivityManager.checkUidPermission(
15363                         INTERACT_ACROSS_USERS,
15364                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15365                     ComponentName comp = new ComponentName(aInfo.packageName, className);
15366                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
15367                             + " requests FLAG_SINGLE_USER, but app does not hold "
15368                             + INTERACT_ACROSS_USERS;
15369                     Slog.w(TAG, msg);
15370                     throw new SecurityException(msg);
15371                 }
15372                 // Permission passed
15373                 result = true;
15374             }
15375         } else if ("system".equals(componentProcessName)) {
15376             result = true;
15377         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15378             // Phone app and persistent apps are allowed to export singleuser providers.
15379             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15380                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15381         }
15382         if (DEBUG_MU) {
15383             Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15384                     + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15385         }
15386         return result;
15387     }
15388
15389     /**
15390      * Checks to see if the caller is in the same app as the singleton
15391      * component, or the component is in a special app. It allows special apps
15392      * to export singleton components but prevents exporting singleton
15393      * components for regular apps.
15394      */
15395     boolean isValidSingletonCall(int callingUid, int componentUid) {
15396         int componentAppId = UserHandle.getAppId(componentUid);
15397         return UserHandle.isSameApp(callingUid, componentUid)
15398                 || componentAppId == Process.SYSTEM_UID
15399                 || componentAppId == Process.PHONE_UID
15400                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15401                         == PackageManager.PERMISSION_GRANTED;
15402     }
15403
15404     public int bindService(IApplicationThread caller, IBinder token,
15405             Intent service, String resolvedType,
15406             IServiceConnection connection, int flags, int userId) {
15407         enforceNotIsolatedCaller("bindService");
15408
15409         // Refuse possible leaked file descriptors
15410         if (service != null && service.hasFileDescriptors() == true) {
15411             throw new IllegalArgumentException("File descriptors passed in Intent");
15412         }
15413
15414         synchronized(this) {
15415             return mServices.bindServiceLocked(caller, token, service, resolvedType,
15416                     connection, flags, userId);
15417         }
15418     }
15419
15420     public boolean unbindService(IServiceConnection connection) {
15421         synchronized (this) {
15422             return mServices.unbindServiceLocked(connection);
15423         }
15424     }
15425
15426     public void publishService(IBinder token, Intent intent, IBinder service) {
15427         // Refuse possible leaked file descriptors
15428         if (intent != null && intent.hasFileDescriptors() == true) {
15429             throw new IllegalArgumentException("File descriptors passed in Intent");
15430         }
15431
15432         synchronized(this) {
15433             if (!(token instanceof ServiceRecord)) {
15434                 throw new IllegalArgumentException("Invalid service token");
15435             }
15436             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15437         }
15438     }
15439
15440     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15441         // Refuse possible leaked file descriptors
15442         if (intent != null && intent.hasFileDescriptors() == true) {
15443             throw new IllegalArgumentException("File descriptors passed in Intent");
15444         }
15445
15446         synchronized(this) {
15447             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15448         }
15449     }
15450
15451     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15452         synchronized(this) {
15453             if (!(token instanceof ServiceRecord)) {
15454                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15455                 throw new IllegalArgumentException("Invalid service token");
15456             }
15457             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15458         }
15459     }
15460     
15461     // =========================================================
15462     // BACKUP AND RESTORE
15463     // =========================================================
15464     
15465     // Cause the target app to be launched if necessary and its backup agent
15466     // instantiated.  The backup agent will invoke backupAgentCreated() on the
15467     // activity manager to announce its creation.
15468     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
15469         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
15470         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15471
15472         IPackageManager pm = AppGlobals.getPackageManager();
15473         ApplicationInfo app = null;
15474         try {
15475             app = pm.getApplicationInfo(packageName, 0, userId);
15476         } catch (RemoteException e) {
15477             // can't happen; package manager is process-local
15478         }
15479         if (app == null) {
15480             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
15481             return false;
15482         }
15483
15484         synchronized(this) {
15485             // !!! TODO: currently no check here that we're already bound
15486             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15487             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15488             synchronized (stats) {
15489                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15490             }
15491
15492             // Backup agent is now in use, its package can't be stopped.
15493             try {
15494                 AppGlobals.getPackageManager().setPackageStoppedState(
15495                         app.packageName, false, UserHandle.getUserId(app.uid));
15496             } catch (RemoteException e) {
15497             } catch (IllegalArgumentException e) {
15498                 Slog.w(TAG, "Failed trying to unstop package "
15499                         + app.packageName + ": " + e);
15500             }
15501
15502             BackupRecord r = new BackupRecord(ss, app, backupMode);
15503             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15504                     ? new ComponentName(app.packageName, app.backupAgentName)
15505                     : new ComponentName("android", "FullBackupAgent");
15506             // startProcessLocked() returns existing proc's record if it's already running
15507             ProcessRecord proc = startProcessLocked(app.processName, app,
15508                     false, 0, "backup", hostingName, false, false, false);
15509             if (proc == null) {
15510                 Slog.e(TAG, "Unable to start backup agent process " + r);
15511                 return false;
15512             }
15513
15514             r.app = proc;
15515             mBackupTarget = r;
15516             mBackupAppName = app.packageName;
15517
15518             // Try not to kill the process during backup
15519             updateOomAdjLocked(proc);
15520
15521             // If the process is already attached, schedule the creation of the backup agent now.
15522             // If it is not yet live, this will be done when it attaches to the framework.
15523             if (proc.thread != null) {
15524                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15525                 try {
15526                     proc.thread.scheduleCreateBackupAgent(app,
15527                             compatibilityInfoForPackageLocked(app), backupMode);
15528                 } catch (RemoteException e) {
15529                     // Will time out on the backup manager side
15530                 }
15531             } else {
15532                 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15533             }
15534             // Invariants: at this point, the target app process exists and the application
15535             // is either already running or in the process of coming up.  mBackupTarget and
15536             // mBackupAppName describe the app, so that when it binds back to the AM we
15537             // know that it's scheduled for a backup-agent operation.
15538         }
15539         
15540         return true;
15541     }
15542
15543     @Override
15544     public void clearPendingBackup() {
15545         if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15546         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15547
15548         synchronized (this) {
15549             mBackupTarget = null;
15550             mBackupAppName = null;
15551         }
15552     }
15553
15554     // A backup agent has just come up
15555     public void backupAgentCreated(String agentPackageName, IBinder agent) {
15556         if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15557                 + " = " + agent);
15558
15559         synchronized(this) {
15560             if (!agentPackageName.equals(mBackupAppName)) {
15561                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15562                 return;
15563             }
15564         }
15565
15566         long oldIdent = Binder.clearCallingIdentity();
15567         try {
15568             IBackupManager bm = IBackupManager.Stub.asInterface(
15569                     ServiceManager.getService(Context.BACKUP_SERVICE));
15570             bm.agentConnected(agentPackageName, agent);
15571         } catch (RemoteException e) {
15572             // can't happen; the backup manager service is local
15573         } catch (Exception e) {
15574             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15575             e.printStackTrace();
15576         } finally {
15577             Binder.restoreCallingIdentity(oldIdent);
15578         }
15579     }
15580
15581     // done with this agent
15582     public void unbindBackupAgent(ApplicationInfo appInfo) {
15583         if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15584         if (appInfo == null) {
15585             Slog.w(TAG, "unbind backup agent for null app");
15586             return;
15587         }
15588
15589         synchronized(this) {
15590             try {
15591                 if (mBackupAppName == null) {
15592                     Slog.w(TAG, "Unbinding backup agent with no active backup");
15593                     return;
15594                 }
15595
15596                 if (!mBackupAppName.equals(appInfo.packageName)) {
15597                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15598                     return;
15599                 }
15600
15601                 // Not backing this app up any more; reset its OOM adjustment
15602                 final ProcessRecord proc = mBackupTarget.app;
15603                 updateOomAdjLocked(proc);
15604
15605                 // If the app crashed during backup, 'thread' will be null here
15606                 if (proc.thread != null) {
15607                     try {
15608                         proc.thread.scheduleDestroyBackupAgent(appInfo,
15609                                 compatibilityInfoForPackageLocked(appInfo));
15610                     } catch (Exception e) {
15611                         Slog.e(TAG, "Exception when unbinding backup agent:");
15612                         e.printStackTrace();
15613                     }
15614                 }
15615             } finally {
15616                 mBackupTarget = null;
15617                 mBackupAppName = null;
15618             }
15619         }
15620     }
15621     // =========================================================
15622     // BROADCASTS
15623     // =========================================================
15624
15625     private final List getStickiesLocked(String action, IntentFilter filter,
15626             List cur, int userId) {
15627         final ContentResolver resolver = mContext.getContentResolver();
15628         ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15629         if (stickies == null) {
15630             return cur;
15631         }
15632         final ArrayList<Intent> list = stickies.get(action);
15633         if (list == null) {
15634             return cur;
15635         }
15636         int N = list.size();
15637         for (int i=0; i<N; i++) {
15638             Intent intent = list.get(i);
15639             if (filter.match(resolver, intent, true, TAG) >= 0) {
15640                 if (cur == null) {
15641                     cur = new ArrayList<Intent>();
15642                 }
15643                 cur.add(intent);
15644             }
15645         }
15646         return cur;
15647     }
15648
15649     boolean isPendingBroadcastProcessLocked(int pid) {
15650         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15651                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15652     }
15653
15654     void skipPendingBroadcastLocked(int pid) {
15655             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15656             for (BroadcastQueue queue : mBroadcastQueues) {
15657                 queue.skipPendingBroadcastLocked(pid);
15658             }
15659     }
15660
15661     // The app just attached; send any pending broadcasts that it should receive
15662     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15663         boolean didSomething = false;
15664         for (BroadcastQueue queue : mBroadcastQueues) {
15665             didSomething |= queue.sendPendingBroadcastsLocked(app);
15666         }
15667         return didSomething;
15668     }
15669
15670     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15671             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15672         enforceNotIsolatedCaller("registerReceiver");
15673         int callingUid;
15674         int callingPid;
15675         synchronized(this) {
15676             ProcessRecord callerApp = null;
15677             if (caller != null) {
15678                 callerApp = getRecordForAppLocked(caller);
15679                 if (callerApp == null) {
15680                     throw new SecurityException(
15681                             "Unable to find app for caller " + caller
15682                             + " (pid=" + Binder.getCallingPid()
15683                             + ") when registering receiver " + receiver);
15684                 }
15685                 if (callerApp.info.uid != Process.SYSTEM_UID &&
15686                         !callerApp.pkgList.containsKey(callerPackage) &&
15687                         !"android".equals(callerPackage)) {
15688                     throw new SecurityException("Given caller package " + callerPackage
15689                             + " is not running in process " + callerApp);
15690                 }
15691                 callingUid = callerApp.info.uid;
15692                 callingPid = callerApp.pid;
15693             } else {
15694                 callerPackage = null;
15695                 callingUid = Binder.getCallingUid();
15696                 callingPid = Binder.getCallingPid();
15697             }
15698
15699             userId = this.handleIncomingUser(callingPid, callingUid, userId,
15700                     true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15701
15702             List allSticky = null;
15703
15704             // Look for any matching sticky broadcasts...
15705             Iterator actions = filter.actionsIterator();
15706             if (actions != null) {
15707                 while (actions.hasNext()) {
15708                     String action = (String)actions.next();
15709                     allSticky = getStickiesLocked(action, filter, allSticky,
15710                             UserHandle.USER_ALL);
15711                     allSticky = getStickiesLocked(action, filter, allSticky,
15712                             UserHandle.getUserId(callingUid));
15713                 }
15714             } else {
15715                 allSticky = getStickiesLocked(null, filter, allSticky,
15716                         UserHandle.USER_ALL);
15717                 allSticky = getStickiesLocked(null, filter, allSticky,
15718                         UserHandle.getUserId(callingUid));
15719             }
15720
15721             // The first sticky in the list is returned directly back to
15722             // the client.
15723             Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15724
15725             if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15726                     + ": " + sticky);
15727
15728             if (receiver == null) {
15729                 return sticky;
15730             }
15731
15732             ReceiverList rl
15733                 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15734             if (rl == null) {
15735                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15736                         userId, receiver);
15737                 if (rl.app != null) {
15738                     rl.app.receivers.add(rl);
15739                 } else {
15740                     try {
15741                         receiver.asBinder().linkToDeath(rl, 0);
15742                     } catch (RemoteException e) {
15743                         return sticky;
15744                     }
15745                     rl.linkedToDeath = true;
15746                 }
15747                 mRegisteredReceivers.put(receiver.asBinder(), rl);
15748             } else if (rl.uid != callingUid) {
15749                 throw new IllegalArgumentException(
15750                         "Receiver requested to register for uid " + callingUid
15751                         + " was previously registered for uid " + rl.uid);
15752             } else if (rl.pid != callingPid) {
15753                 throw new IllegalArgumentException(
15754                         "Receiver requested to register for pid " + callingPid
15755                         + " was previously registered for pid " + rl.pid);
15756             } else if (rl.userId != userId) {
15757                 throw new IllegalArgumentException(
15758                         "Receiver requested to register for user " + userId
15759                         + " was previously registered for user " + rl.userId);
15760             }
15761             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15762                     permission, callingUid, userId);
15763             rl.add(bf);
15764             if (!bf.debugCheck()) {
15765                 Slog.w(TAG, "==> For Dynamic broadast");
15766             }
15767             mReceiverResolver.addFilter(bf);
15768
15769             // Enqueue broadcasts for all existing stickies that match
15770             // this filter.
15771             if (allSticky != null) {
15772                 ArrayList receivers = new ArrayList();
15773                 receivers.add(bf);
15774
15775                 int N = allSticky.size();
15776                 for (int i=0; i<N; i++) {
15777                     Intent intent = (Intent)allSticky.get(i);
15778                     BroadcastQueue queue = broadcastQueueForIntent(intent);
15779                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15780                             null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15781                             null, null, false, true, true, -1);
15782                     queue.enqueueParallelBroadcastLocked(r);
15783                     queue.scheduleBroadcastsLocked();
15784                 }
15785             }
15786
15787             return sticky;
15788         }
15789     }
15790
15791     public void unregisterReceiver(IIntentReceiver receiver) {
15792         if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15793
15794         final long origId = Binder.clearCallingIdentity();
15795         try {
15796             boolean doTrim = false;
15797
15798             synchronized(this) {
15799                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15800                 if (rl != null) {
15801                     if (rl.curBroadcast != null) {
15802                         BroadcastRecord r = rl.curBroadcast;
15803                         final boolean doNext = finishReceiverLocked(
15804                                 receiver.asBinder(), r.resultCode, r.resultData,
15805                                 r.resultExtras, r.resultAbort);
15806                         if (doNext) {
15807                             doTrim = true;
15808                             r.queue.processNextBroadcast(false);
15809                         }
15810                     }
15811
15812                     if (rl.app != null) {
15813                         rl.app.receivers.remove(rl);
15814                     }
15815                     removeReceiverLocked(rl);
15816                     if (rl.linkedToDeath) {
15817                         rl.linkedToDeath = false;
15818                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
15819                     }
15820                 }
15821             }
15822
15823             // If we actually concluded any broadcasts, we might now be able
15824             // to trim the recipients' apps from our working set
15825             if (doTrim) {
15826                 trimApplications();
15827                 return;
15828             }
15829
15830         } finally {
15831             Binder.restoreCallingIdentity(origId);
15832         }
15833     }
15834
15835     void removeReceiverLocked(ReceiverList rl) {
15836         mRegisteredReceivers.remove(rl.receiver.asBinder());
15837         int N = rl.size();
15838         for (int i=0; i<N; i++) {
15839             mReceiverResolver.removeFilter(rl.get(i));
15840         }
15841     }
15842     
15843     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15844         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15845             ProcessRecord r = mLruProcesses.get(i);
15846             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15847                 try {
15848                     r.thread.dispatchPackageBroadcast(cmd, packages);
15849                 } catch (RemoteException ex) {
15850                 }
15851             }
15852         }
15853     }
15854
15855     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15856             int callingUid, int[] users) {
15857         List<ResolveInfo> receivers = null;
15858         try {
15859             HashSet<ComponentName> singleUserReceivers = null;
15860             boolean scannedFirstReceivers = false;
15861             for (int user : users) {
15862                 // Skip users that have Shell restrictions
15863                 if (callingUid == Process.SHELL_UID
15864                         && getUserManagerLocked().hasUserRestriction(
15865                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15866                     continue;
15867                 }
15868                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15869                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15870                 if (user != 0 && newReceivers != null) {
15871                     // If this is not the primary user, we need to check for
15872                     // any receivers that should be filtered out.
15873                     for (int i=0; i<newReceivers.size(); i++) {
15874                         ResolveInfo ri = newReceivers.get(i);
15875                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15876                             newReceivers.remove(i);
15877                             i--;
15878                         }
15879                     }
15880                 }
15881                 if (newReceivers != null && newReceivers.size() == 0) {
15882                     newReceivers = null;
15883                 }
15884                 if (receivers == null) {
15885                     receivers = newReceivers;
15886                 } else if (newReceivers != null) {
15887                     // We need to concatenate the additional receivers
15888                     // found with what we have do far.  This would be easy,
15889                     // but we also need to de-dup any receivers that are
15890                     // singleUser.
15891                     if (!scannedFirstReceivers) {
15892                         // Collect any single user receivers we had already retrieved.
15893                         scannedFirstReceivers = true;
15894                         for (int i=0; i<receivers.size(); i++) {
15895                             ResolveInfo ri = receivers.get(i);
15896                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15897                                 ComponentName cn = new ComponentName(
15898                                         ri.activityInfo.packageName, ri.activityInfo.name);
15899                                 if (singleUserReceivers == null) {
15900                                     singleUserReceivers = new HashSet<ComponentName>();
15901                                 }
15902                                 singleUserReceivers.add(cn);
15903                             }
15904                         }
15905                     }
15906                     // Add the new results to the existing results, tracking
15907                     // and de-dupping single user receivers.
15908                     for (int i=0; i<newReceivers.size(); i++) {
15909                         ResolveInfo ri = newReceivers.get(i);
15910                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15911                             ComponentName cn = new ComponentName(
15912                                     ri.activityInfo.packageName, ri.activityInfo.name);
15913                             if (singleUserReceivers == null) {
15914                                 singleUserReceivers = new HashSet<ComponentName>();
15915                             }
15916                             if (!singleUserReceivers.contains(cn)) {
15917                                 singleUserReceivers.add(cn);
15918                                 receivers.add(ri);
15919                             }
15920                         } else {
15921                             receivers.add(ri);
15922                         }
15923                     }
15924                 }
15925             }
15926         } catch (RemoteException ex) {
15927             // pm is in same process, this will never happen.
15928         }
15929         return receivers;
15930     }
15931
15932     private final int broadcastIntentLocked(ProcessRecord callerApp,
15933             String callerPackage, Intent intent, String resolvedType,
15934             IIntentReceiver resultTo, int resultCode, String resultData,
15935             Bundle map, String requiredPermission, int appOp,
15936             boolean ordered, boolean sticky, int callingPid, int callingUid,
15937             int userId) {
15938         intent = new Intent(intent);
15939
15940         // By default broadcasts do not go to stopped apps.
15941         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15942
15943         if (DEBUG_BROADCAST_LIGHT) Slog.v(
15944             TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15945             + " ordered=" + ordered + " userid=" + userId);
15946         if ((resultTo != null) && !ordered) {
15947             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15948         }
15949
15950         userId = handleIncomingUser(callingPid, callingUid, userId,
15951                 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15952
15953         // Make sure that the user who is receiving this broadcast is running.
15954         // If not, we will just skip it. Make an exception for shutdown broadcasts
15955         // and upgrade steps.
15956
15957         if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15958             if ((callingUid != Process.SYSTEM_UID
15959                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15960                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15961                 Slog.w(TAG, "Skipping broadcast of " + intent
15962                         + ": user " + userId + " is stopped");
15963                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15964             }
15965         }
15966
15967         /*
15968          * Prevent non-system code (defined here to be non-persistent
15969          * processes) from sending protected broadcasts.
15970          */
15971         int callingAppId = UserHandle.getAppId(callingUid);
15972         if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15973             || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15974             || callingAppId == Process.NFC_UID || callingUid == 0) {
15975             // Always okay.
15976         } else if (callerApp == null || !callerApp.persistent) {
15977             try {
15978                 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15979                         intent.getAction())) {
15980                     String msg = "Permission Denial: not allowed to send broadcast "
15981                             + intent.getAction() + " from pid="
15982                             + callingPid + ", uid=" + callingUid;
15983                     Slog.w(TAG, msg);
15984                     throw new SecurityException(msg);
15985                 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15986                     // Special case for compatibility: we don't want apps to send this,
15987                     // but historically it has not been protected and apps may be using it
15988                     // to poke their own app widget.  So, instead of making it protected,
15989                     // just limit it to the caller.
15990                     if (callerApp == null) {
15991                         String msg = "Permission Denial: not allowed to send broadcast "
15992                                 + intent.getAction() + " from unknown caller.";
15993                         Slog.w(TAG, msg);
15994                         throw new SecurityException(msg);
15995                     } else if (intent.getComponent() != null) {
15996                         // They are good enough to send to an explicit component...  verify
15997                         // it is being sent to the calling app.
15998                         if (!intent.getComponent().getPackageName().equals(
15999                                 callerApp.info.packageName)) {
16000                             String msg = "Permission Denial: not allowed to send broadcast "
16001                                     + intent.getAction() + " to "
16002                                     + intent.getComponent().getPackageName() + " from "
16003                                     + callerApp.info.packageName;
16004                             Slog.w(TAG, msg);
16005                             throw new SecurityException(msg);
16006                         }
16007                     } else {
16008                         // Limit broadcast to their own package.
16009                         intent.setPackage(callerApp.info.packageName);
16010                     }
16011                 }
16012             } catch (RemoteException e) {
16013                 Slog.w(TAG, "Remote exception", e);
16014                 return ActivityManager.BROADCAST_SUCCESS;
16015             }
16016         }
16017
16018         final String action = intent.getAction();
16019         if (action != null) {
16020             switch (action) {
16021                 case Intent.ACTION_UID_REMOVED:
16022                 case Intent.ACTION_PACKAGE_REMOVED:
16023                 case Intent.ACTION_PACKAGE_CHANGED:
16024                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16025                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16026                     // Handle special intents: if this broadcast is from the package
16027                     // manager about a package being removed, we need to remove all of
16028                     // its activities from the history stack.
16029                     if (checkComponentPermission(
16030                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16031                             callingPid, callingUid, -1, true)
16032                             != PackageManager.PERMISSION_GRANTED) {
16033                         String msg = "Permission Denial: " + intent.getAction()
16034                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
16035                                 + ", uid=" + callingUid + ")"
16036                                 + " requires "
16037                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16038                         Slog.w(TAG, msg);
16039                         throw new SecurityException(msg);
16040                     }
16041                     switch (action) {
16042                         case Intent.ACTION_UID_REMOVED:
16043                             final Bundle intentExtras = intent.getExtras();
16044                             final int uid = intentExtras != null
16045                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16046                             if (uid >= 0) {
16047                                 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
16048                                 synchronized (bs) {
16049                                     bs.removeUidStatsLocked(uid);
16050                                 }
16051                                 mAppOpsService.uidRemoved(uid);
16052                             }
16053                             break;
16054                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16055                             // If resources are unavailable just force stop all those packages
16056                             // and flush the attribute cache as well.
16057                             String list[] =
16058                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16059                             if (list != null && list.length > 0) {
16060                                 for (int i = 0; i < list.length; i++) {
16061                                     forceStopPackageLocked(list[i], -1, false, true, true,
16062                                             false, false, userId, "storage unmount");
16063                                 }
16064                                 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16065                                 sendPackageBroadcastLocked(
16066                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16067                                         userId);
16068                             }
16069                             break;
16070                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16071                             cleanupRecentTasksLocked(UserHandle.USER_ALL);
16072                             break;
16073                         case Intent.ACTION_PACKAGE_REMOVED:
16074                         case Intent.ACTION_PACKAGE_CHANGED:
16075                             Uri data = intent.getData();
16076                             String ssp;
16077                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16078                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16079                                 boolean fullUninstall = removed &&
16080                                         !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16081                                 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16082                                     forceStopPackageLocked(ssp, UserHandle.getAppId(
16083                                             intent.getIntExtra(Intent.EXTRA_UID, -1)),
16084                                             false, true, true, false, fullUninstall, userId,
16085                                             removed ? "pkg removed" : "pkg changed");
16086                                 }
16087                                 if (removed) {
16088                                     sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16089                                             new String[] {ssp}, userId);
16090                                     if (fullUninstall) {
16091                                         mAppOpsService.packageRemoved(
16092                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16093
16094                                         // Remove all permissions granted from/to this package
16095                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
16096
16097                                         removeTasksByPackageNameLocked(ssp, userId);
16098                                         if (userId == UserHandle.USER_OWNER) {
16099                                             mTaskPersister.removeFromPackageCache(ssp);
16100                                         }
16101                                     }
16102                                 } else {
16103                                     removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16104                                     if (userId == UserHandle.USER_OWNER) {
16105                                         mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16106                                     }
16107                                 }
16108                             }
16109                             break;
16110                     }
16111                     break;
16112                 case Intent.ACTION_PACKAGE_ADDED:
16113                     // Special case for adding a package: by default turn on compatibility mode.
16114                     Uri data = intent.getData();
16115                     String ssp;
16116                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16117                         final boolean replacing =
16118                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16119                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16120
16121                         if (replacing) {
16122                             removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16123                         }
16124                         if (userId == UserHandle.USER_OWNER) {
16125                             mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16126                         }
16127                     }
16128                     break;
16129                 case Intent.ACTION_TIMEZONE_CHANGED:
16130                     // If this is the time zone changed action, queue up a message that will reset
16131                     // the timezone of all currently running processes. This message will get
16132                     // queued up before the broadcast happens.
16133                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16134                     break;
16135                 case Intent.ACTION_TIME_CHANGED:
16136                     // If the user set the time, let all running processes know.
16137                     final int is24Hour =
16138                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16139                                     : 0;
16140                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16141                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16142                     synchronized (stats) {
16143                         stats.noteCurrentTimeChangedLocked();
16144                     }
16145                     break;
16146                 case Intent.ACTION_CLEAR_DNS_CACHE:
16147                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16148                     break;
16149                 case Proxy.PROXY_CHANGE_ACTION:
16150                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16151                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16152                     break;
16153             }
16154         }
16155
16156         // Add to the sticky list if requested.
16157         if (sticky) {
16158             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16159                     callingPid, callingUid)
16160                     != PackageManager.PERMISSION_GRANTED) {
16161                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16162                         + callingPid + ", uid=" + callingUid
16163                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16164                 Slog.w(TAG, msg);
16165                 throw new SecurityException(msg);
16166             }
16167             if (requiredPermission != null) {
16168                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16169                         + " and enforce permission " + requiredPermission);
16170                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16171             }
16172             if (intent.getComponent() != null) {
16173                 throw new SecurityException(
16174                         "Sticky broadcasts can't target a specific component");
16175             }
16176             // We use userId directly here, since the "all" target is maintained
16177             // as a separate set of sticky broadcasts.
16178             if (userId != UserHandle.USER_ALL) {
16179                 // But first, if this is not a broadcast to all users, then
16180                 // make sure it doesn't conflict with an existing broadcast to
16181                 // all users.
16182                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16183                         UserHandle.USER_ALL);
16184                 if (stickies != null) {
16185                     ArrayList<Intent> list = stickies.get(intent.getAction());
16186                     if (list != null) {
16187                         int N = list.size();
16188                         int i;
16189                         for (i=0; i<N; i++) {
16190                             if (intent.filterEquals(list.get(i))) {
16191                                 throw new IllegalArgumentException(
16192                                         "Sticky broadcast " + intent + " for user "
16193                                         + userId + " conflicts with existing global broadcast");
16194                             }
16195                         }
16196                     }
16197                 }
16198             }
16199             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16200             if (stickies == null) {
16201                 stickies = new ArrayMap<String, ArrayList<Intent>>();
16202                 mStickyBroadcasts.put(userId, stickies);
16203             }
16204             ArrayList<Intent> list = stickies.get(intent.getAction());
16205             if (list == null) {
16206                 list = new ArrayList<Intent>();
16207                 stickies.put(intent.getAction(), list);
16208             }
16209             int N = list.size();
16210             int i;
16211             for (i=0; i<N; i++) {
16212                 if (intent.filterEquals(list.get(i))) {
16213                     // This sticky already exists, replace it.
16214                     list.set(i, new Intent(intent));
16215                     break;
16216                 }
16217             }
16218             if (i >= N) {
16219                 list.add(new Intent(intent));
16220             }
16221         }
16222
16223         int[] users;
16224         if (userId == UserHandle.USER_ALL) {
16225             // Caller wants broadcast to go to all started users.
16226             users = mStartedUserArray;
16227         } else {
16228             // Caller wants broadcast to go to one specific user.
16229             users = new int[] {userId};
16230         }
16231
16232         // Figure out who all will receive this broadcast.
16233         List receivers = null;
16234         List<BroadcastFilter> registeredReceivers = null;
16235         // Need to resolve the intent to interested receivers...
16236         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16237                  == 0) {
16238             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16239         }
16240         if (intent.getComponent() == null) {
16241             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16242                 // Query one target user at a time, excluding shell-restricted users
16243                 UserManagerService ums = getUserManagerLocked();
16244                 for (int i = 0; i < users.length; i++) {
16245                     if (ums.hasUserRestriction(
16246                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16247                         continue;
16248                     }
16249                     List<BroadcastFilter> registeredReceiversForUser =
16250                             mReceiverResolver.queryIntent(intent,
16251                                     resolvedType, false, users[i]);
16252                     if (registeredReceivers == null) {
16253                         registeredReceivers = registeredReceiversForUser;
16254                     } else if (registeredReceiversForUser != null) {
16255                         registeredReceivers.addAll(registeredReceiversForUser);
16256                     }
16257                 }
16258             } else {
16259                 registeredReceivers = mReceiverResolver.queryIntent(intent,
16260                         resolvedType, false, userId);
16261             }
16262         }
16263
16264         final boolean replacePending =
16265                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16266         
16267         if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16268                 + " replacePending=" + replacePending);
16269         
16270         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16271         if (!ordered && NR > 0) {
16272             // If we are not serializing this broadcast, then send the
16273             // registered receivers separately so they don't wait for the
16274             // components to be launched.
16275             final BroadcastQueue queue = broadcastQueueForIntent(intent);
16276             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16277                     callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16278                     appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16279                     ordered, sticky, false, userId);
16280             if (DEBUG_BROADCAST) Slog.v(
16281                     TAG, "Enqueueing parallel broadcast " + r);
16282             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16283             if (!replaced) {
16284                 queue.enqueueParallelBroadcastLocked(r);
16285                 queue.scheduleBroadcastsLocked();
16286             }
16287             registeredReceivers = null;
16288             NR = 0;
16289         }
16290
16291         // Merge into one list.
16292         int ir = 0;
16293         if (receivers != null) {
16294             // A special case for PACKAGE_ADDED: do not allow the package
16295             // being added to see this broadcast.  This prevents them from
16296             // using this as a back door to get run as soon as they are
16297             // installed.  Maybe in the future we want to have a special install
16298             // broadcast or such for apps, but we'd like to deliberately make
16299             // this decision.
16300             String skipPackages[] = null;
16301             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16302                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16303                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16304                 Uri data = intent.getData();
16305                 if (data != null) {
16306                     String pkgName = data.getSchemeSpecificPart();
16307                     if (pkgName != null) {
16308                         skipPackages = new String[] { pkgName };
16309                     }
16310                 }
16311             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16312                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16313             }
16314             if (skipPackages != null && (skipPackages.length > 0)) {
16315                 for (String skipPackage : skipPackages) {
16316                     if (skipPackage != null) {
16317                         int NT = receivers.size();
16318                         for (int it=0; it<NT; it++) {
16319                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
16320                             if (curt.activityInfo.packageName.equals(skipPackage)) {
16321                                 receivers.remove(it);
16322                                 it--;
16323                                 NT--;
16324                             }
16325                         }
16326                     }
16327                 }
16328             }
16329
16330             int NT = receivers != null ? receivers.size() : 0;
16331             int it = 0;
16332             ResolveInfo curt = null;
16333             BroadcastFilter curr = null;
16334             while (it < NT && ir < NR) {
16335                 if (curt == null) {
16336                     curt = (ResolveInfo)receivers.get(it);
16337                 }
16338                 if (curr == null) {
16339                     curr = registeredReceivers.get(ir);
16340                 }
16341                 if (curr.getPriority() >= curt.priority) {
16342                     // Insert this broadcast record into the final list.
16343                     receivers.add(it, curr);
16344                     ir++;
16345                     curr = null;
16346                     it++;
16347                     NT++;
16348                 } else {
16349                     // Skip to the next ResolveInfo in the final list.
16350                     it++;
16351                     curt = null;
16352                 }
16353             }
16354         }
16355         while (ir < NR) {
16356             if (receivers == null) {
16357                 receivers = new ArrayList();
16358             }
16359             receivers.add(registeredReceivers.get(ir));
16360             ir++;
16361         }
16362
16363         if ((receivers != null && receivers.size() > 0)
16364                 || resultTo != null) {
16365             BroadcastQueue queue = broadcastQueueForIntent(intent);
16366             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16367                     callerPackage, callingPid, callingUid, resolvedType,
16368                     requiredPermission, appOp, receivers, resultTo, resultCode,
16369                     resultData, map, ordered, sticky, false, userId);
16370             if (DEBUG_BROADCAST) Slog.v(
16371                     TAG, "Enqueueing ordered broadcast " + r
16372                     + ": prev had " + queue.mOrderedBroadcasts.size());
16373             if (DEBUG_BROADCAST) {
16374                 int seq = r.intent.getIntExtra("seq", -1);
16375                 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16376             }
16377             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
16378             if (!replaced) {
16379                 queue.enqueueOrderedBroadcastLocked(r);
16380                 queue.scheduleBroadcastsLocked();
16381             }
16382         }
16383
16384         return ActivityManager.BROADCAST_SUCCESS;
16385     }
16386
16387     final Intent verifyBroadcastLocked(Intent intent) {
16388         // Refuse possible leaked file descriptors
16389         if (intent != null && intent.hasFileDescriptors() == true) {
16390             throw new IllegalArgumentException("File descriptors passed in Intent");
16391         }
16392
16393         int flags = intent.getFlags();
16394
16395         if (!mProcessesReady) {
16396             // if the caller really truly claims to know what they're doing, go
16397             // ahead and allow the broadcast without launching any receivers
16398             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16399                 intent = new Intent(intent);
16400                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16401             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16402                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16403                         + " before boot completion");
16404                 throw new IllegalStateException("Cannot broadcast before boot completed");
16405             }
16406         }
16407
16408         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16409             throw new IllegalArgumentException(
16410                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16411         }
16412
16413         return intent;
16414     }
16415
16416     public final int broadcastIntent(IApplicationThread caller,
16417             Intent intent, String resolvedType, IIntentReceiver resultTo,
16418             int resultCode, String resultData, Bundle map,
16419             String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16420         enforceNotIsolatedCaller("broadcastIntent");
16421         synchronized(this) {
16422             intent = verifyBroadcastLocked(intent);
16423
16424             final ProcessRecord callerApp = getRecordForAppLocked(caller);
16425             final int callingPid = Binder.getCallingPid();
16426             final int callingUid = Binder.getCallingUid();
16427             final long origId = Binder.clearCallingIdentity();
16428             int res = broadcastIntentLocked(callerApp,
16429                     callerApp != null ? callerApp.info.packageName : null,
16430                     intent, resolvedType, resultTo,
16431                     resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16432                     callingPid, callingUid, userId);
16433             Binder.restoreCallingIdentity(origId);
16434             return res;
16435         }
16436     }
16437
16438     int broadcastIntentInPackage(String packageName, int uid,
16439             Intent intent, String resolvedType, IIntentReceiver resultTo,
16440             int resultCode, String resultData, Bundle map,
16441             String requiredPermission, boolean serialized, boolean sticky, int userId) {
16442         synchronized(this) {
16443             intent = verifyBroadcastLocked(intent);
16444
16445             final long origId = Binder.clearCallingIdentity();
16446             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16447                     resultTo, resultCode, resultData, map, requiredPermission,
16448                     AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16449             Binder.restoreCallingIdentity(origId);
16450             return res;
16451         }
16452     }
16453
16454     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16455         // Refuse possible leaked file descriptors
16456         if (intent != null && intent.hasFileDescriptors() == true) {
16457             throw new IllegalArgumentException("File descriptors passed in Intent");
16458         }
16459
16460         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16461                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16462
16463         synchronized(this) {
16464             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16465                     != PackageManager.PERMISSION_GRANTED) {
16466                 String msg = "Permission Denial: unbroadcastIntent() from pid="
16467                         + Binder.getCallingPid()
16468                         + ", uid=" + Binder.getCallingUid()
16469                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16470                 Slog.w(TAG, msg);
16471                 throw new SecurityException(msg);
16472             }
16473             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16474             if (stickies != null) {
16475                 ArrayList<Intent> list = stickies.get(intent.getAction());
16476                 if (list != null) {
16477                     int N = list.size();
16478                     int i;
16479                     for (i=0; i<N; i++) {
16480                         if (intent.filterEquals(list.get(i))) {
16481                             list.remove(i);
16482                             break;
16483                         }
16484                     }
16485                     if (list.size() <= 0) {
16486                         stickies.remove(intent.getAction());
16487                     }
16488                 }
16489                 if (stickies.size() <= 0) {
16490                     mStickyBroadcasts.remove(userId);
16491                 }
16492             }
16493         }
16494     }
16495
16496     private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16497             String resultData, Bundle resultExtras, boolean resultAbort) {
16498         final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16499         if (r == null) {
16500             Slog.w(TAG, "finishReceiver called but not found on queue");
16501             return false;
16502         }
16503
16504         return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16505     }
16506
16507     void backgroundServicesFinishedLocked(int userId) {
16508         for (BroadcastQueue queue : mBroadcastQueues) {
16509             queue.backgroundServicesFinishedLocked(userId);
16510         }
16511     }
16512
16513     public void finishReceiver(IBinder who, int resultCode, String resultData,
16514             Bundle resultExtras, boolean resultAbort) {
16515         if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16516
16517         // Refuse possible leaked file descriptors
16518         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16519             throw new IllegalArgumentException("File descriptors passed in Bundle");
16520         }
16521
16522         final long origId = Binder.clearCallingIdentity();
16523         try {
16524             boolean doNext = false;
16525             BroadcastRecord r;
16526
16527             synchronized(this) {
16528                 r = broadcastRecordForReceiverLocked(who);
16529                 if (r != null) {
16530                     doNext = r.queue.finishReceiverLocked(r, resultCode,
16531                         resultData, resultExtras, resultAbort, true);
16532                 }
16533             }
16534
16535             if (doNext) {
16536                 r.queue.processNextBroadcast(false);
16537             }
16538             trimApplications();
16539         } finally {
16540             Binder.restoreCallingIdentity(origId);
16541         }
16542     }
16543     
16544     // =========================================================
16545     // INSTRUMENTATION
16546     // =========================================================
16547
16548     public boolean startInstrumentation(ComponentName className,
16549             String profileFile, int flags, Bundle arguments,
16550             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16551             int userId, String abiOverride) {
16552         enforceNotIsolatedCaller("startInstrumentation");
16553         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16554                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16555         // Refuse possible leaked file descriptors
16556         if (arguments != null && arguments.hasFileDescriptors()) {
16557             throw new IllegalArgumentException("File descriptors passed in Bundle");
16558         }
16559
16560         synchronized(this) {
16561             InstrumentationInfo ii = null;
16562             ApplicationInfo ai = null;
16563             try {
16564                 ii = mContext.getPackageManager().getInstrumentationInfo(
16565                     className, STOCK_PM_FLAGS);
16566                 ai = AppGlobals.getPackageManager().getApplicationInfo(
16567                         ii.targetPackage, STOCK_PM_FLAGS, userId);
16568             } catch (PackageManager.NameNotFoundException e) {
16569             } catch (RemoteException e) {
16570             }
16571             if (ii == null) {
16572                 reportStartInstrumentationFailure(watcher, className,
16573                         "Unable to find instrumentation info for: " + className);
16574                 return false;
16575             }
16576             if (ai == null) {
16577                 reportStartInstrumentationFailure(watcher, className,
16578                         "Unable to find instrumentation target package: " + ii.targetPackage);
16579                 return false;
16580             }
16581
16582             int match = mContext.getPackageManager().checkSignatures(
16583                     ii.targetPackage, ii.packageName);
16584             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16585                 String msg = "Permission Denial: starting instrumentation "
16586                         + className + " from pid="
16587                         + Binder.getCallingPid()
16588                         + ", uid=" + Binder.getCallingPid()
16589                         + " not allowed because package " + ii.packageName
16590                         + " does not have a signature matching the target "
16591                         + ii.targetPackage;
16592                 reportStartInstrumentationFailure(watcher, className, msg);
16593                 throw new SecurityException(msg);
16594             }
16595
16596             final long origId = Binder.clearCallingIdentity();
16597             // Instrumentation can kill and relaunch even persistent processes
16598             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16599                     "start instr");
16600             ProcessRecord app = addAppLocked(ai, false, abiOverride);
16601             app.instrumentationClass = className;
16602             app.instrumentationInfo = ai;
16603             app.instrumentationProfileFile = profileFile;
16604             app.instrumentationArguments = arguments;
16605             app.instrumentationWatcher = watcher;
16606             app.instrumentationUiAutomationConnection = uiAutomationConnection;
16607             app.instrumentationResultClass = className;
16608             Binder.restoreCallingIdentity(origId);
16609         }
16610
16611         return true;
16612     }
16613     
16614     /**
16615      * Report errors that occur while attempting to start Instrumentation.  Always writes the 
16616      * error to the logs, but if somebody is watching, send the report there too.  This enables
16617      * the "am" command to report errors with more information.
16618      * 
16619      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16620      * @param cn The component name of the instrumentation.
16621      * @param report The error report.
16622      */
16623     private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 
16624             ComponentName cn, String report) {
16625         Slog.w(TAG, report);
16626         try {
16627             if (watcher != null) {
16628                 Bundle results = new Bundle();
16629                 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16630                 results.putString("Error", report);
16631                 watcher.instrumentationStatus(cn, -1, results);
16632             }
16633         } catch (RemoteException e) {
16634             Slog.w(TAG, e);
16635         }
16636     }
16637
16638     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16639         if (app.instrumentationWatcher != null) {
16640             try {
16641                 // NOTE:  IInstrumentationWatcher *must* be oneway here
16642                 app.instrumentationWatcher.instrumentationFinished(
16643                     app.instrumentationClass,
16644                     resultCode,
16645                     results);
16646             } catch (RemoteException e) {
16647             }
16648         }
16649         if (app.instrumentationUiAutomationConnection != null) {
16650             try {
16651                 app.instrumentationUiAutomationConnection.shutdown();
16652             } catch (RemoteException re) {
16653                 /* ignore */
16654             }
16655             // Only a UiAutomation can set this flag and now that
16656             // it is finished we make sure it is reset to its default.
16657             mUserIsMonkey = false;
16658         }
16659         app.instrumentationWatcher = null;
16660         app.instrumentationUiAutomationConnection = null;
16661         app.instrumentationClass = null;
16662         app.instrumentationInfo = null;
16663         app.instrumentationProfileFile = null;
16664         app.instrumentationArguments = null;
16665
16666         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16667                 "finished inst");
16668     }
16669
16670     public void finishInstrumentation(IApplicationThread target,
16671             int resultCode, Bundle results) {
16672         int userId = UserHandle.getCallingUserId();
16673         // Refuse possible leaked file descriptors
16674         if (results != null && results.hasFileDescriptors()) {
16675             throw new IllegalArgumentException("File descriptors passed in Intent");
16676         }
16677
16678         synchronized(this) {
16679             ProcessRecord app = getRecordForAppLocked(target);
16680             if (app == null) {
16681                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16682                 return;
16683             }
16684             final long origId = Binder.clearCallingIdentity();
16685             finishInstrumentationLocked(app, resultCode, results);
16686             Binder.restoreCallingIdentity(origId);
16687         }
16688     }
16689
16690     // =========================================================
16691     // CONFIGURATION
16692     // =========================================================
16693     
16694     public ConfigurationInfo getDeviceConfigurationInfo() {
16695         ConfigurationInfo config = new ConfigurationInfo();
16696         synchronized (this) {
16697             config.reqTouchScreen = mConfiguration.touchscreen;
16698             config.reqKeyboardType = mConfiguration.keyboard;
16699             config.reqNavigation = mConfiguration.navigation;
16700             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16701                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16702                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16703             }
16704             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16705                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16706                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16707             }
16708             config.reqGlEsVersion = GL_ES_VERSION;
16709         }
16710         return config;
16711     }
16712
16713     ActivityStack getFocusedStack() {
16714         return mStackSupervisor.getFocusedStack();
16715     }
16716
16717     public Configuration getConfiguration() {
16718         Configuration ci;
16719         synchronized(this) {
16720             ci = new Configuration(mConfiguration);
16721             ci.userSetLocale = false;
16722         }
16723         return ci;
16724     }
16725
16726     public void updatePersistentConfiguration(Configuration values) {
16727         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16728                 "updateConfiguration()");
16729         enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16730                 "updateConfiguration()");
16731         if (values == null) {
16732             throw new NullPointerException("Configuration must not be null");
16733         }
16734
16735         synchronized(this) {
16736             final long origId = Binder.clearCallingIdentity();
16737             updateConfigurationLocked(values, null, true, false);
16738             Binder.restoreCallingIdentity(origId);
16739         }
16740     }
16741
16742     public void updateConfiguration(Configuration values) {
16743         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16744                 "updateConfiguration()");
16745
16746         synchronized(this) {
16747             if (values == null && mWindowManager != null) {
16748                 // sentinel: fetch the current configuration from the window manager
16749                 values = mWindowManager.computeNewConfiguration();
16750             }
16751
16752             if (mWindowManager != null) {
16753                 mProcessList.applyDisplaySize(mWindowManager);
16754             }
16755
16756             final long origId = Binder.clearCallingIdentity();
16757             if (values != null) {
16758                 Settings.System.clearConfiguration(values);
16759             }
16760             updateConfigurationLocked(values, null, false, false);
16761             Binder.restoreCallingIdentity(origId);
16762         }
16763     }
16764
16765     /**
16766      * Do either or both things: (1) change the current configuration, and (2)
16767      * make sure the given activity is running with the (now) current
16768      * configuration.  Returns true if the activity has been left running, or
16769      * false if <var>starting</var> is being destroyed to match the new
16770      * configuration.
16771      * @param persistent TODO
16772      */
16773     boolean updateConfigurationLocked(Configuration values,
16774             ActivityRecord starting, boolean persistent, boolean initLocale) {
16775         int changes = 0;
16776
16777         if (values != null) {
16778             Configuration newConfig = new Configuration(mConfiguration);
16779             changes = newConfig.updateFrom(values);
16780             if (changes != 0) {
16781                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16782                     Slog.i(TAG, "Updating configuration to: " + values);
16783                 }
16784                 
16785                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16786
16787                 if (values.locale != null && !initLocale) {
16788                     saveLocaleLocked(values.locale, 
16789                                      !values.locale.equals(mConfiguration.locale),
16790                                      values.userSetLocale);
16791                 }
16792
16793                 mConfigurationSeq++;
16794                 if (mConfigurationSeq <= 0) {
16795                     mConfigurationSeq = 1;
16796                 }
16797                 newConfig.seq = mConfigurationSeq;
16798                 mConfiguration = newConfig;
16799                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16800                 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16801                 //mUsageStatsService.noteStartConfig(newConfig);
16802
16803                 final Configuration configCopy = new Configuration(mConfiguration);
16804                 
16805                 // TODO: If our config changes, should we auto dismiss any currently
16806                 // showing dialogs?
16807                 mShowDialogs = shouldShowDialogs(newConfig);
16808
16809                 AttributeCache ac = AttributeCache.instance();
16810                 if (ac != null) {
16811                     ac.updateConfiguration(configCopy);
16812                 }
16813
16814                 // Make sure all resources in our process are updated
16815                 // right now, so that anyone who is going to retrieve
16816                 // resource values after we return will be sure to get
16817                 // the new ones.  This is especially important during
16818                 // boot, where the first config change needs to guarantee
16819                 // all resources have that config before following boot
16820                 // code is executed.
16821                 mSystemThread.applyConfigurationToResources(configCopy);
16822
16823                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16824                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16825                     msg.obj = new Configuration(configCopy);
16826                     mHandler.sendMessage(msg);
16827                 }
16828
16829                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16830                     ProcessRecord app = mLruProcesses.get(i);
16831                     try {
16832                         if (app.thread != null) {
16833                             if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16834                                     + app.processName + " new config " + mConfiguration);
16835                             app.thread.scheduleConfigurationChanged(configCopy);
16836                         }
16837                     } catch (Exception e) {
16838                     }
16839                 }
16840                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16841                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16842                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
16843                         | Intent.FLAG_RECEIVER_FOREGROUND);
16844                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16845                         null, AppOpsManager.OP_NONE, false, false, MY_PID,
16846                         Process.SYSTEM_UID, UserHandle.USER_ALL);
16847                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16848                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16849                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16850                     if (!mProcessesReady) {
16851                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16852                     }
16853                     broadcastIntentLocked(null, null, intent,
16854                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16855                             false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16856                 }
16857             }
16858         }
16859
16860         boolean kept = true;
16861         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16862         // mainStack is null during startup.
16863         if (mainStack != null) {
16864             if (changes != 0 && starting == null) {
16865                 // If the configuration changed, and the caller is not already
16866                 // in the process of starting an activity, then find the top
16867                 // activity to check if its configuration needs to change.
16868                 starting = mainStack.topRunningActivityLocked(null);
16869             }
16870
16871             if (starting != null) {
16872                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16873                 // And we need to make sure at this point that all other activities
16874                 // are made visible with the correct configuration.
16875                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16876             }
16877         }
16878
16879         if (values != null && mWindowManager != null) {
16880             mWindowManager.setNewConfiguration(mConfiguration);
16881         }
16882
16883         return kept;
16884     }
16885
16886     /**
16887      * Decide based on the configuration whether we should shouw the ANR,
16888      * crash, etc dialogs.  The idea is that if there is no affordnace to
16889      * press the on-screen buttons, we shouldn't show the dialog.
16890      *
16891      * A thought: SystemUI might also want to get told about this, the Power
16892      * dialog / global actions also might want different behaviors.
16893      */
16894     private static final boolean shouldShowDialogs(Configuration config) {
16895         return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16896                 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16897     }
16898
16899     /**
16900      * Save the locale.  You must be inside a synchronized (this) block.
16901      */
16902     private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16903         if(isDiff) {
16904             SystemProperties.set("user.language", l.getLanguage());
16905             SystemProperties.set("user.region", l.getCountry());
16906         } 
16907
16908         if(isPersist) {
16909             SystemProperties.set("persist.sys.language", l.getLanguage());
16910             SystemProperties.set("persist.sys.country", l.getCountry());
16911             SystemProperties.set("persist.sys.localevar", l.getVariant());
16912
16913             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16914         }
16915     }
16916
16917     @Override
16918     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16919         synchronized (this) {
16920             ActivityRecord srec = ActivityRecord.forToken(token);
16921             if (srec.task != null && srec.task.stack != null) {
16922                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16923             }
16924         }
16925         return false;
16926     }
16927
16928     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16929             Intent resultData) {
16930
16931         synchronized (this) {
16932             final ActivityStack stack = ActivityRecord.getStackLocked(token);
16933             if (stack != null) {
16934                 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16935             }
16936             return false;
16937         }
16938     }
16939
16940     public int getLaunchedFromUid(IBinder activityToken) {
16941         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16942         if (srec == null) {
16943             return -1;
16944         }
16945         return srec.launchedFromUid;
16946     }
16947
16948     public String getLaunchedFromPackage(IBinder activityToken) {
16949         ActivityRecord srec = ActivityRecord.forToken(activityToken);
16950         if (srec == null) {
16951             return null;
16952         }
16953         return srec.launchedFromPackage;
16954     }
16955
16956     // =========================================================
16957     // LIFETIME MANAGEMENT
16958     // =========================================================
16959
16960     // Returns which broadcast queue the app is the current [or imminent] receiver
16961     // on, or 'null' if the app is not an active broadcast recipient.
16962     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16963         BroadcastRecord r = app.curReceiver;
16964         if (r != null) {
16965             return r.queue;
16966         }
16967
16968         // It's not the current receiver, but it might be starting up to become one
16969         synchronized (this) {
16970             for (BroadcastQueue queue : mBroadcastQueues) {
16971                 r = queue.mPendingBroadcast;
16972                 if (r != null && r.curApp == app) {
16973                     // found it; report which queue it's in
16974                     return queue;
16975                 }
16976             }
16977         }
16978
16979         return null;
16980     }
16981
16982     Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16983             ComponentName targetComponent, String targetProcess) {
16984         if (!mTrackingAssociations) {
16985             return null;
16986         }
16987         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16988                 = mAssociations.get(targetUid);
16989         if (components == null) {
16990             components = new ArrayMap<>();
16991             mAssociations.put(targetUid, components);
16992         }
16993         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16994         if (sourceUids == null) {
16995             sourceUids = new SparseArray<>();
16996             components.put(targetComponent, sourceUids);
16997         }
16998         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16999         if (sourceProcesses == null) {
17000             sourceProcesses = new ArrayMap<>();
17001             sourceUids.put(sourceUid, sourceProcesses);
17002         }
17003         Association ass = sourceProcesses.get(sourceProcess);
17004         if (ass == null) {
17005             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17006                     targetProcess);
17007             sourceProcesses.put(sourceProcess, ass);
17008         }
17009         ass.mCount++;
17010         ass.mNesting++;
17011         if (ass.mNesting == 1) {
17012             ass.mStartTime = SystemClock.uptimeMillis();
17013         }
17014         return ass;
17015     }
17016
17017     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17018             ComponentName targetComponent) {
17019         if (!mTrackingAssociations) {
17020             return;
17021         }
17022         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17023                 = mAssociations.get(targetUid);
17024         if (components == null) {
17025             return;
17026         }
17027         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17028         if (sourceUids == null) {
17029             return;
17030         }
17031         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17032         if (sourceProcesses == null) {
17033             return;
17034         }
17035         Association ass = sourceProcesses.get(sourceProcess);
17036         if (ass == null || ass.mNesting <= 0) {
17037             return;
17038         }
17039         ass.mNesting--;
17040         if (ass.mNesting == 0) {
17041             ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17042         }
17043     }
17044
17045     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17046             boolean doingAll, long now) {
17047         if (mAdjSeq == app.adjSeq) {
17048             // This adjustment has already been computed.
17049             return app.curRawAdj;
17050         }
17051
17052         if (app.thread == null) {
17053             app.adjSeq = mAdjSeq;
17054             app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17055             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17056             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17057         }
17058
17059         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17060         app.adjSource = null;
17061         app.adjTarget = null;
17062         app.empty = false;
17063         app.cached = false;
17064
17065         final int activitiesSize = app.activities.size();
17066
17067         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17068             // The max adjustment doesn't allow this app to be anything
17069             // below foreground, so it is not worth doing work for it.
17070             app.adjType = "fixed";
17071             app.adjSeq = mAdjSeq;
17072             app.curRawAdj = app.maxAdj;
17073             app.foregroundActivities = false;
17074             app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17075             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17076             // System processes can do UI, and when they do we want to have
17077             // them trim their memory after the user leaves the UI.  To
17078             // facilitate this, here we need to determine whether or not it
17079             // is currently showing UI.
17080             app.systemNoUi = true;
17081             if (app == TOP_APP) {
17082                 app.systemNoUi = false;
17083             } else if (activitiesSize > 0) {
17084                 for (int j = 0; j < activitiesSize; j++) {
17085                     final ActivityRecord r = app.activities.get(j);
17086                     if (r.visible) {
17087                         app.systemNoUi = false;
17088                     }
17089                 }
17090             }
17091             if (!app.systemNoUi) {
17092                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17093             }
17094             return (app.curAdj=app.maxAdj);
17095         }
17096
17097         app.systemNoUi = false;
17098
17099         // Determine the importance of the process, starting with most
17100         // important to least, and assign an appropriate OOM adjustment.
17101         int adj;
17102         int schedGroup;
17103         int procState;
17104         boolean foregroundActivities = false;
17105         BroadcastQueue queue;
17106         if (app == TOP_APP) {
17107             // The last app on the list is the foreground app.
17108             adj = ProcessList.FOREGROUND_APP_ADJ;
17109             schedGroup = Process.THREAD_GROUP_DEFAULT;
17110             app.adjType = "top-activity";
17111             foregroundActivities = true;
17112             procState = ActivityManager.PROCESS_STATE_TOP;
17113         } else if (app.instrumentationClass != null) {
17114             // Don't want to kill running instrumentation.
17115             adj = ProcessList.FOREGROUND_APP_ADJ;
17116             schedGroup = Process.THREAD_GROUP_DEFAULT;
17117             app.adjType = "instrumentation";
17118             procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17119         } else if ((queue = isReceivingBroadcast(app)) != null) {
17120             // An app that is currently receiving a broadcast also
17121             // counts as being in the foreground for OOM killer purposes.
17122             // It's placed in a sched group based on the nature of the
17123             // broadcast as reflected by which queue it's active in.
17124             adj = ProcessList.FOREGROUND_APP_ADJ;
17125             schedGroup = (queue == mFgBroadcastQueue)
17126                     ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17127             app.adjType = "broadcast";
17128             procState = ActivityManager.PROCESS_STATE_RECEIVER;
17129         } else if (app.executingServices.size() > 0) {
17130             // An app that is currently executing a service callback also
17131             // counts as being in the foreground.
17132             adj = ProcessList.FOREGROUND_APP_ADJ;
17133             schedGroup = app.execServicesFg ?
17134                     Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17135             app.adjType = "exec-service";
17136             procState = ActivityManager.PROCESS_STATE_SERVICE;
17137             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17138         } else {
17139             // As far as we know the process is empty.  We may change our mind later.
17140             schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17141             // At this point we don't actually know the adjustment.  Use the cached adj
17142             // value that the caller wants us to.
17143             adj = cachedAdj;
17144             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17145             app.cached = true;
17146             app.empty = true;
17147             app.adjType = "cch-empty";
17148         }
17149
17150         // Examine all activities if not already foreground.
17151         if (!foregroundActivities && activitiesSize > 0) {
17152             for (int j = 0; j < activitiesSize; j++) {
17153                 final ActivityRecord r = app.activities.get(j);
17154                 if (r.app != app) {
17155                     Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17156                             + app + "?!?");
17157                     continue;
17158                 }
17159                 if (r.visible) {
17160                     // App has a visible activity; only upgrade adjustment.
17161                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17162                         adj = ProcessList.VISIBLE_APP_ADJ;
17163                         app.adjType = "visible";
17164                     }
17165                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
17166                         procState = ActivityManager.PROCESS_STATE_TOP;
17167                     }
17168                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17169                     app.cached = false;
17170                     app.empty = false;
17171                     foregroundActivities = true;
17172                     break;
17173                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17174                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17175                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17176                         app.adjType = "pausing";
17177                     }
17178                     if (procState > ActivityManager.PROCESS_STATE_TOP) {
17179                         procState = ActivityManager.PROCESS_STATE_TOP;
17180                     }
17181                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17182                     app.cached = false;
17183                     app.empty = false;
17184                     foregroundActivities = true;
17185                 } else if (r.state == ActivityState.STOPPING) {
17186                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17187                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17188                         app.adjType = "stopping";
17189                     }
17190                     // For the process state, we will at this point consider the
17191                     // process to be cached.  It will be cached either as an activity
17192                     // or empty depending on whether the activity is finishing.  We do
17193                     // this so that we can treat the process as cached for purposes of
17194                     // memory trimming (determing current memory level, trim command to
17195                     // send to process) since there can be an arbitrary number of stopping
17196                     // processes and they should soon all go into the cached state.
17197                     if (!r.finishing) {
17198                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17199                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17200                         }
17201                     }
17202                     app.cached = false;
17203                     app.empty = false;
17204                     foregroundActivities = true;
17205                 } else {
17206                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17207                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17208                         app.adjType = "cch-act";
17209                     }
17210                 }
17211             }
17212         }
17213
17214         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17215             if (app.foregroundServices) {
17216                 // The user is aware of this app, so make it visible.
17217                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17218                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17219                 app.cached = false;
17220                 app.adjType = "fg-service";
17221                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17222             } else if (app.forcingToForeground != null) {
17223                 // The user is aware of this app, so make it visible.
17224                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17225                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17226                 app.cached = false;
17227                 app.adjType = "force-fg";
17228                 app.adjSource = app.forcingToForeground;
17229                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17230             }
17231         }
17232
17233         if (app == mHeavyWeightProcess) {
17234             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17235                 // We don't want to kill the current heavy-weight process.
17236                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17237                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17238                 app.cached = false;
17239                 app.adjType = "heavy";
17240             }
17241             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17242                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17243             }
17244         }
17245
17246         if (app == mHomeProcess) {
17247             if (adj > ProcessList.HOME_APP_ADJ) {
17248                 // This process is hosting what we currently consider to be the
17249                 // home app, so we don't want to let it go into the background.
17250                 adj = ProcessList.HOME_APP_ADJ;
17251                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17252                 app.cached = false;
17253                 app.adjType = "home";
17254             }
17255             if (procState > ActivityManager.PROCESS_STATE_HOME) {
17256                 procState = ActivityManager.PROCESS_STATE_HOME;
17257             }
17258         }
17259
17260         if (app == mPreviousProcess && app.activities.size() > 0) {
17261             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17262                 // This was the previous process that showed UI to the user.
17263                 // We want to try to keep it around more aggressively, to give
17264                 // a good experience around switching between two apps.
17265                 adj = ProcessList.PREVIOUS_APP_ADJ;
17266                 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17267                 app.cached = false;
17268                 app.adjType = "previous";
17269             }
17270             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17271                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17272             }
17273         }
17274
17275         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17276                 + " reason=" + app.adjType);
17277
17278         // By default, we use the computed adjustment.  It may be changed if
17279         // there are applications dependent on our services or providers, but
17280         // this gives us a baseline and makes sure we don't get into an
17281         // infinite recursion.
17282         app.adjSeq = mAdjSeq;
17283         app.curRawAdj = adj;
17284         app.hasStartedServices = false;
17285
17286         if (mBackupTarget != null && app == mBackupTarget.app) {
17287             // If possible we want to avoid killing apps while they're being backed up
17288             if (adj > ProcessList.BACKUP_APP_ADJ) {
17289                 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17290                 adj = ProcessList.BACKUP_APP_ADJ;
17291                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17292                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17293                 }
17294                 app.adjType = "backup";
17295                 app.cached = false;
17296             }
17297             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17298                 procState = ActivityManager.PROCESS_STATE_BACKUP;
17299             }
17300         }
17301
17302         boolean mayBeTop = false;
17303
17304         for (int is = app.services.size()-1;
17305                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17306                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17307                         || procState > ActivityManager.PROCESS_STATE_TOP);
17308                 is--) {
17309             ServiceRecord s = app.services.valueAt(is);
17310             if (s.startRequested) {
17311                 app.hasStartedServices = true;
17312                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17313                     procState = ActivityManager.PROCESS_STATE_SERVICE;
17314                 }
17315                 if (app.hasShownUi && app != mHomeProcess) {
17316                     // If this process has shown some UI, let it immediately
17317                     // go to the LRU list because it may be pretty heavy with
17318                     // UI stuff.  We'll tag it with a label just to help
17319                     // debug and understand what is going on.
17320                     if (adj > ProcessList.SERVICE_ADJ) {
17321                         app.adjType = "cch-started-ui-services";
17322                     }
17323                 } else {
17324                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17325                         // This service has seen some activity within
17326                         // recent memory, so we will keep its process ahead
17327                         // of the background processes.
17328                         if (adj > ProcessList.SERVICE_ADJ) {
17329                             adj = ProcessList.SERVICE_ADJ;
17330                             app.adjType = "started-services";
17331                             app.cached = false;
17332                         }
17333                     }
17334                     // If we have let the service slide into the background
17335                     // state, still have some text describing what it is doing
17336                     // even though the service no longer has an impact.
17337                     if (adj > ProcessList.SERVICE_ADJ) {
17338                         app.adjType = "cch-started-services";
17339                     }
17340                 }
17341             }
17342             for (int conni = s.connections.size()-1;
17343                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17344                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17345                             || procState > ActivityManager.PROCESS_STATE_TOP);
17346                     conni--) {
17347                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17348                 for (int i = 0;
17349                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17350                                 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17351                                 || procState > ActivityManager.PROCESS_STATE_TOP);
17352                         i++) {
17353                     // XXX should compute this based on the max of
17354                     // all connected clients.
17355                     ConnectionRecord cr = clist.get(i);
17356                     if (cr.binding.client == app) {
17357                         // Binding to ourself is not interesting.
17358                         continue;
17359                     }
17360                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17361                         ProcessRecord client = cr.binding.client;
17362                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
17363                                 TOP_APP, doingAll, now);
17364                         int clientProcState = client.curProcState;
17365                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17366                             // If the other app is cached for any reason, for purposes here
17367                             // we are going to consider it empty.  The specific cached state
17368                             // doesn't propagate except under certain conditions.
17369                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17370                         }
17371                         String adjType = null;
17372                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17373                             // Not doing bind OOM management, so treat
17374                             // this guy more like a started service.
17375                             if (app.hasShownUi && app != mHomeProcess) {
17376                                 // If this process has shown some UI, let it immediately
17377                                 // go to the LRU list because it may be pretty heavy with
17378                                 // UI stuff.  We'll tag it with a label just to help
17379                                 // debug and understand what is going on.
17380                                 if (adj > clientAdj) {
17381                                     adjType = "cch-bound-ui-services";
17382                                 }
17383                                 app.cached = false;
17384                                 clientAdj = adj;
17385                                 clientProcState = procState;
17386                             } else {
17387                                 if (now >= (s.lastActivity
17388                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17389                                     // This service has not seen activity within
17390                                     // recent memory, so allow it to drop to the
17391                                     // LRU list if there is no other reason to keep
17392                                     // it around.  We'll also tag it with a label just
17393                                     // to help debug and undertand what is going on.
17394                                     if (adj > clientAdj) {
17395                                         adjType = "cch-bound-services";
17396                                     }
17397                                     clientAdj = adj;
17398                                 }
17399                             }
17400                         }
17401                         if (adj > clientAdj) {
17402                             // If this process has recently shown UI, and
17403                             // the process that is binding to it is less
17404                             // important than being visible, then we don't
17405                             // care about the binding as much as we care
17406                             // about letting this process get into the LRU
17407                             // list to be killed and restarted if needed for
17408                             // memory.
17409                             if (app.hasShownUi && app != mHomeProcess
17410                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17411                                 adjType = "cch-bound-ui-services";
17412                             } else {
17413                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17414                                         |Context.BIND_IMPORTANT)) != 0) {
17415                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17416                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17417                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17418                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17419                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17420                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17421                                 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17422                                     adj = clientAdj;
17423                                 } else {
17424                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
17425                                         adj = ProcessList.VISIBLE_APP_ADJ;
17426                                     }
17427                                 }
17428                                 if (!client.cached) {
17429                                     app.cached = false;
17430                                 }
17431                                 adjType = "service";
17432                             }
17433                         }
17434                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17435                             if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17436                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17437                             }
17438                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17439                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17440                                     // Special handling of clients who are in the top state.
17441                                     // We *may* want to consider this process to be in the
17442                                     // top state as well, but only if there is not another
17443                                     // reason for it to be running.  Being on the top is a
17444                                     // special state, meaning you are specifically running
17445                                     // for the current top app.  If the process is already
17446                                     // running in the background for some other reason, it
17447                                     // is more important to continue considering it to be
17448                                     // in the background state.
17449                                     mayBeTop = true;
17450                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17451                                 } else {
17452                                     // Special handling for above-top states (persistent
17453                                     // processes).  These should not bring the current process
17454                                     // into the top state, since they are not on top.  Instead
17455                                     // give them the best state after that.
17456                                     clientProcState =
17457                                             ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17458                                 }
17459                             }
17460                         } else {
17461                             if (clientProcState <
17462                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17463                                 clientProcState =
17464                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17465                             }
17466                         }
17467                         if (procState > clientProcState) {
17468                             procState = clientProcState;
17469                         }
17470                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17471                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17472                             app.pendingUiClean = true;
17473                         }
17474                         if (adjType != null) {
17475                             app.adjType = adjType;
17476                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17477                                     .REASON_SERVICE_IN_USE;
17478                             app.adjSource = cr.binding.client;
17479                             app.adjSourceProcState = clientProcState;
17480                             app.adjTarget = s.name;
17481                         }
17482                     }
17483                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17484                         app.treatLikeActivity = true;
17485                     }
17486                     final ActivityRecord a = cr.activity;
17487                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17488                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17489                                 (a.visible || a.state == ActivityState.RESUMED
17490                                  || a.state == ActivityState.PAUSING)) {
17491                             adj = ProcessList.FOREGROUND_APP_ADJ;
17492                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17493                                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17494                             }
17495                             app.cached = false;
17496                             app.adjType = "service";
17497                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17498                                     .REASON_SERVICE_IN_USE;
17499                             app.adjSource = a;
17500                             app.adjSourceProcState = procState;
17501                             app.adjTarget = s.name;
17502                         }
17503                     }
17504                 }
17505             }
17506         }
17507
17508         for (int provi = app.pubProviders.size()-1;
17509                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17510                         || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17511                         || procState > ActivityManager.PROCESS_STATE_TOP);
17512                 provi--) {
17513             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17514             for (int i = cpr.connections.size()-1;
17515                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17516                             || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17517                             || procState > ActivityManager.PROCESS_STATE_TOP);
17518                     i--) {
17519                 ContentProviderConnection conn = cpr.connections.get(i);
17520                 ProcessRecord client = conn.client;
17521                 if (client == app) {
17522                     // Being our own client is not interesting.
17523                     continue;
17524                 }
17525                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17526                 int clientProcState = client.curProcState;
17527                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17528                     // If the other app is cached for any reason, for purposes here
17529                     // we are going to consider it empty.
17530                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17531                 }
17532                 if (adj > clientAdj) {
17533                     if (app.hasShownUi && app != mHomeProcess
17534                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17535                         app.adjType = "cch-ui-provider";
17536                     } else {
17537                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17538                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17539                         app.adjType = "provider";
17540                     }
17541                     app.cached &= client.cached;
17542                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17543                             .REASON_PROVIDER_IN_USE;
17544                     app.adjSource = client;
17545                     app.adjSourceProcState = clientProcState;
17546                     app.adjTarget = cpr.name;
17547                 }
17548                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17549                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17550                         // Special handling of clients who are in the top state.
17551                         // We *may* want to consider this process to be in the
17552                         // top state as well, but only if there is not another
17553                         // reason for it to be running.  Being on the top is a
17554                         // special state, meaning you are specifically running
17555                         // for the current top app.  If the process is already
17556                         // running in the background for some other reason, it
17557                         // is more important to continue considering it to be
17558                         // in the background state.
17559                         mayBeTop = true;
17560                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17561                     } else {
17562                         // Special handling for above-top states (persistent
17563                         // processes).  These should not bring the current process
17564                         // into the top state, since they are not on top.  Instead
17565                         // give them the best state after that.
17566                         clientProcState =
17567                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17568                     }
17569                 }
17570                 if (procState > clientProcState) {
17571                     procState = clientProcState;
17572                 }
17573                 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17574                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17575                 }
17576             }
17577             // If the provider has external (non-framework) process
17578             // dependencies, ensure that its adjustment is at least
17579             // FOREGROUND_APP_ADJ.
17580             if (cpr.hasExternalProcessHandles()) {
17581                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17582                     adj = ProcessList.FOREGROUND_APP_ADJ;
17583                     schedGroup = Process.THREAD_GROUP_DEFAULT;
17584                     app.cached = false;
17585                     app.adjType = "provider";
17586                     app.adjTarget = cpr.name;
17587                 }
17588                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17589                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17590                 }
17591             }
17592         }
17593
17594         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17595             // A client of one of our services or providers is in the top state.  We
17596             // *may* want to be in the top state, but not if we are already running in
17597             // the background for some other reason.  For the decision here, we are going
17598             // to pick out a few specific states that we want to remain in when a client
17599             // is top (states that tend to be longer-term) and otherwise allow it to go
17600             // to the top state.
17601             switch (procState) {
17602                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17603                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17604                 case ActivityManager.PROCESS_STATE_SERVICE:
17605                     // These all are longer-term states, so pull them up to the top
17606                     // of the background states, but not all the way to the top state.
17607                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17608                     break;
17609                 default:
17610                     // Otherwise, top is a better choice, so take it.
17611                     procState = ActivityManager.PROCESS_STATE_TOP;
17612                     break;
17613             }
17614         }
17615
17616         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17617             if (app.hasClientActivities) {
17618                 // This is a cached process, but with client activities.  Mark it so.
17619                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17620                 app.adjType = "cch-client-act";
17621             } else if (app.treatLikeActivity) {
17622                 // This is a cached process, but somebody wants us to treat it like it has
17623                 // an activity, okay!
17624                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17625                 app.adjType = "cch-as-act";
17626             }
17627         }
17628
17629         if (adj == ProcessList.SERVICE_ADJ) {
17630             if (doingAll) {
17631                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17632                 mNewNumServiceProcs++;
17633                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17634                 if (!app.serviceb) {
17635                     // This service isn't far enough down on the LRU list to
17636                     // normally be a B service, but if we are low on RAM and it
17637                     // is large we want to force it down since we would prefer to
17638                     // keep launcher over it.
17639                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17640                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17641                         app.serviceHighRam = true;
17642                         app.serviceb = true;
17643                         //Slog.i(TAG, "ADJ " + app + " high ram!");
17644                     } else {
17645                         mNewNumAServiceProcs++;
17646                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
17647                     }
17648                 } else {
17649                     app.serviceHighRam = false;
17650                 }
17651             }
17652             if (app.serviceb) {
17653                 adj = ProcessList.SERVICE_B_ADJ;
17654             }
17655         }
17656
17657         app.curRawAdj = adj;
17658         
17659         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17660         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17661         if (adj > app.maxAdj) {
17662             adj = app.maxAdj;
17663             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17664                 schedGroup = Process.THREAD_GROUP_DEFAULT;
17665             }
17666         }
17667
17668         // Do final modification to adj.  Everything we do between here and applying
17669         // the final setAdj must be done in this function, because we will also use
17670         // it when computing the final cached adj later.  Note that we don't need to
17671         // worry about this for max adj above, since max adj will always be used to
17672         // keep it out of the cached vaues.
17673         app.curAdj = app.modifyRawOomAdj(adj);
17674         app.curSchedGroup = schedGroup;
17675         app.curProcState = procState;
17676         app.foregroundActivities = foregroundActivities;
17677
17678         return app.curRawAdj;
17679     }
17680
17681     /**
17682      * Record new PSS sample for a process.
17683      */
17684     void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17685         proc.lastPssTime = now;
17686         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17687         if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17688                 + ": " + pss + " lastPss=" + proc.lastPss
17689                 + " state=" + ProcessList.makeProcStateString(procState));
17690         if (proc.initialIdlePss == 0) {
17691             proc.initialIdlePss = pss;
17692         }
17693         proc.lastPss = pss;
17694         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17695             proc.lastCachedPss = pss;
17696         }
17697     }
17698
17699     /**
17700      * Schedule PSS collection of a process.
17701      */
17702     void requestPssLocked(ProcessRecord proc, int procState) {
17703         if (mPendingPssProcesses.contains(proc)) {
17704             return;
17705         }
17706         if (mPendingPssProcesses.size() == 0) {
17707             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17708         }
17709         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17710         proc.pssProcState = procState;
17711         mPendingPssProcesses.add(proc);
17712     }
17713
17714     /**
17715      * Schedule PSS collection of all processes.
17716      */
17717     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17718         if (!always) {
17719             if (now < (mLastFullPssTime +
17720                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17721                 return;
17722             }
17723         }
17724         if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17725         mLastFullPssTime = now;
17726         mFullPssPending = true;
17727         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17728         mPendingPssProcesses.clear();
17729         for (int i=mLruProcesses.size()-1; i>=0; i--) {
17730             ProcessRecord app = mLruProcesses.get(i);
17731             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17732                 app.pssProcState = app.setProcState;
17733                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17734                         mTestPssMode, isSleeping(), now);
17735                 mPendingPssProcesses.add(app);
17736             }
17737         }
17738         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17739     }
17740
17741     public void setTestPssMode(boolean enabled) {
17742         synchronized (this) {
17743             mTestPssMode = enabled;
17744             if (enabled) {
17745                 // Whenever we enable the mode, we want to take a snapshot all of current
17746                 // process mem use.
17747                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17748             }
17749         }
17750     }
17751
17752     /**
17753      * Ask a given process to GC right now.
17754      */
17755     final void performAppGcLocked(ProcessRecord app) {
17756         try {
17757             app.lastRequestedGc = SystemClock.uptimeMillis();
17758             if (app.thread != null) {
17759                 if (app.reportLowMemory) {
17760                     app.reportLowMemory = false;
17761                     app.thread.scheduleLowMemory();
17762                 } else {
17763                     app.thread.processInBackground();
17764                 }
17765             }
17766         } catch (Exception e) {
17767             // whatever.
17768         }
17769     }
17770     
17771     /**
17772      * Returns true if things are idle enough to perform GCs.
17773      */
17774     private final boolean canGcNowLocked() {
17775         boolean processingBroadcasts = false;
17776         for (BroadcastQueue q : mBroadcastQueues) {
17777             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17778                 processingBroadcasts = true;
17779             }
17780         }
17781         return !processingBroadcasts
17782                 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17783     }
17784     
17785     /**
17786      * Perform GCs on all processes that are waiting for it, but only
17787      * if things are idle.
17788      */
17789     final void performAppGcsLocked() {
17790         final int N = mProcessesToGc.size();
17791         if (N <= 0) {
17792             return;
17793         }
17794         if (canGcNowLocked()) {
17795             while (mProcessesToGc.size() > 0) {
17796                 ProcessRecord proc = mProcessesToGc.remove(0);
17797                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17798                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17799                             <= SystemClock.uptimeMillis()) {
17800                         // To avoid spamming the system, we will GC processes one
17801                         // at a time, waiting a few seconds between each.
17802                         performAppGcLocked(proc);
17803                         scheduleAppGcsLocked();
17804                         return;
17805                     } else {
17806                         // It hasn't been long enough since we last GCed this
17807                         // process...  put it in the list to wait for its time.
17808                         addProcessToGcListLocked(proc);
17809                         break;
17810                     }
17811                 }
17812             }
17813             
17814             scheduleAppGcsLocked();
17815         }
17816     }
17817     
17818     /**
17819      * If all looks good, perform GCs on all processes waiting for them.
17820      */
17821     final void performAppGcsIfAppropriateLocked() {
17822         if (canGcNowLocked()) {
17823             performAppGcsLocked();
17824             return;
17825         }
17826         // Still not idle, wait some more.
17827         scheduleAppGcsLocked();
17828     }
17829
17830     /**
17831      * Schedule the execution of all pending app GCs.
17832      */
17833     final void scheduleAppGcsLocked() {
17834         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17835         
17836         if (mProcessesToGc.size() > 0) {
17837             // Schedule a GC for the time to the next process.
17838             ProcessRecord proc = mProcessesToGc.get(0);
17839             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17840             
17841             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17842             long now = SystemClock.uptimeMillis();
17843             if (when < (now+GC_TIMEOUT)) {
17844                 when = now + GC_TIMEOUT;
17845             }
17846             mHandler.sendMessageAtTime(msg, when);
17847         }
17848     }
17849     
17850     /**
17851      * Add a process to the array of processes waiting to be GCed.  Keeps the
17852      * list in sorted order by the last GC time.  The process can't already be
17853      * on the list.
17854      */
17855     final void addProcessToGcListLocked(ProcessRecord proc) {
17856         boolean added = false;
17857         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17858             if (mProcessesToGc.get(i).lastRequestedGc <
17859                     proc.lastRequestedGc) {
17860                 added = true;
17861                 mProcessesToGc.add(i+1, proc);
17862                 break;
17863             }
17864         }
17865         if (!added) {
17866             mProcessesToGc.add(0, proc);
17867         }
17868     }
17869     
17870     /**
17871      * Set up to ask a process to GC itself.  This will either do it
17872      * immediately, or put it on the list of processes to gc the next
17873      * time things are idle.
17874      */
17875     final void scheduleAppGcLocked(ProcessRecord app) {
17876         long now = SystemClock.uptimeMillis();
17877         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17878             return;
17879         }
17880         if (!mProcessesToGc.contains(app)) {
17881             addProcessToGcListLocked(app);
17882             scheduleAppGcsLocked();
17883         }
17884     }
17885
17886     final void checkExcessivePowerUsageLocked(boolean doKills) {
17887         updateCpuStatsNow();
17888
17889         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17890         boolean doWakeKills = doKills;
17891         boolean doCpuKills = doKills;
17892         if (mLastPowerCheckRealtime == 0) {
17893             doWakeKills = false;
17894         }
17895         if (mLastPowerCheckUptime == 0) {
17896             doCpuKills = false;
17897         }
17898         if (stats.isScreenOn()) {
17899             doWakeKills = false;
17900         }
17901         final long curRealtime = SystemClock.elapsedRealtime();
17902         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17903         final long curUptime = SystemClock.uptimeMillis();
17904         final long uptimeSince = curUptime - mLastPowerCheckUptime;
17905         mLastPowerCheckRealtime = curRealtime;
17906         mLastPowerCheckUptime = curUptime;
17907         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17908             doWakeKills = false;
17909         }
17910         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17911             doCpuKills = false;
17912         }
17913         int i = mLruProcesses.size();
17914         while (i > 0) {
17915             i--;
17916             ProcessRecord app = mLruProcesses.get(i);
17917             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17918                 long wtime;
17919                 synchronized (stats) {
17920                     wtime = stats.getProcessWakeTime(app.info.uid,
17921                             app.pid, curRealtime);
17922                 }
17923                 long wtimeUsed = wtime - app.lastWakeTime;
17924                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17925                 if (DEBUG_POWER) {
17926                     StringBuilder sb = new StringBuilder(128);
17927                     sb.append("Wake for ");
17928                     app.toShortString(sb);
17929                     sb.append(": over ");
17930                     TimeUtils.formatDuration(realtimeSince, sb);
17931                     sb.append(" used ");
17932                     TimeUtils.formatDuration(wtimeUsed, sb);
17933                     sb.append(" (");
17934                     sb.append((wtimeUsed*100)/realtimeSince);
17935                     sb.append("%)");
17936                     Slog.i(TAG, sb.toString());
17937                     sb.setLength(0);
17938                     sb.append("CPU for ");
17939                     app.toShortString(sb);
17940                     sb.append(": over ");
17941                     TimeUtils.formatDuration(uptimeSince, sb);
17942                     sb.append(" used ");
17943                     TimeUtils.formatDuration(cputimeUsed, sb);
17944                     sb.append(" (");
17945                     sb.append((cputimeUsed*100)/uptimeSince);
17946                     sb.append("%)");
17947                     Slog.i(TAG, sb.toString());
17948                 }
17949                 // If a process has held a wake lock for more
17950                 // than 50% of the time during this period,
17951                 // that sounds bad.  Kill!
17952                 if (doWakeKills && realtimeSince > 0
17953                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
17954                     synchronized (stats) {
17955                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17956                                 realtimeSince, wtimeUsed);
17957                     }
17958                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17959                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17960                 } else if (doCpuKills && uptimeSince > 0
17961                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
17962                     synchronized (stats) {
17963                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17964                                 uptimeSince, cputimeUsed);
17965                     }
17966                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17967                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17968                 } else {
17969                     app.lastWakeTime = wtime;
17970                     app.lastCpuTime = app.curCpuTime;
17971                 }
17972             }
17973         }
17974     }
17975
17976     private final boolean applyOomAdjLocked(ProcessRecord app,
17977             ProcessRecord TOP_APP, boolean doingAll, long now) {
17978         boolean success = true;
17979
17980         if (app.curRawAdj != app.setRawAdj) {
17981             app.setRawAdj = app.curRawAdj;
17982         }
17983
17984         int changes = 0;
17985
17986         if (app.curAdj != app.setAdj) {
17987             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17988             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17989                 TAG, "Set " + app.pid + " " + app.processName +
17990                 " adj " + app.curAdj + ": " + app.adjType);
17991             app.setAdj = app.curAdj;
17992         }
17993
17994         if (app.setSchedGroup != app.curSchedGroup) {
17995             app.setSchedGroup = app.curSchedGroup;
17996             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17997                     "Setting process group of " + app.processName
17998                     + " to " + app.curSchedGroup);
17999             if (app.waitingToKill != null &&
18000                     app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18001                 app.kill(app.waitingToKill, true);
18002                 success = false;
18003             } else {
18004                 if (true) {
18005                     long oldId = Binder.clearCallingIdentity();
18006                     try {
18007                         Process.setProcessGroup(app.pid, app.curSchedGroup);
18008                     } catch (Exception e) {
18009                         Slog.w(TAG, "Failed setting process group of " + app.pid
18010                                 + " to " + app.curSchedGroup);
18011                         e.printStackTrace();
18012                     } finally {
18013                         Binder.restoreCallingIdentity(oldId);
18014                     }
18015                 } else {
18016                     if (app.thread != null) {
18017                         try {
18018                             app.thread.setSchedulingGroup(app.curSchedGroup);
18019                         } catch (RemoteException e) {
18020                         }
18021                     }
18022                 }
18023                 Process.setSwappiness(app.pid,
18024                         app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18025             }
18026         }
18027         if (app.repForegroundActivities != app.foregroundActivities) {
18028             app.repForegroundActivities = app.foregroundActivities;
18029             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18030         }
18031         if (app.repProcState != app.curProcState) {
18032             app.repProcState = app.curProcState;
18033             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18034             if (app.thread != null) {
18035                 try {
18036                     if (false) {
18037                         //RuntimeException h = new RuntimeException("here");
18038                         Slog.i(TAG, "Sending new process state " + app.repProcState
18039                                 + " to " + app /*, h*/);
18040                     }
18041                     app.thread.setProcessState(app.repProcState);
18042                 } catch (RemoteException e) {
18043                 }
18044             }
18045         }
18046         if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
18047                 app.setProcState)) {
18048             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18049                 // Experimental code to more aggressively collect pss while
18050                 // running test...  the problem is that this tends to collect
18051                 // the data right when a process is transitioning between process
18052                 // states, which well tend to give noisy data.
18053                 long start = SystemClock.uptimeMillis();
18054                 long pss = Debug.getPss(app.pid, mTmpLong, null);
18055                 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
18056                 mPendingPssProcesses.remove(app);
18057                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18058                         + " to " + app.curProcState + ": "
18059                         + (SystemClock.uptimeMillis()-start) + "ms");
18060             }
18061             app.lastStateTime = now;
18062             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18063                     mTestPssMode, isSleeping(), now);
18064             if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
18065                     + ProcessList.makeProcStateString(app.setProcState) + " to "
18066                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18067                     + (app.nextPssTime-now) + ": " + app);
18068         } else {
18069             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18070                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18071                     mTestPssMode)))) {
18072                 requestPssLocked(app, app.setProcState);
18073                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18074                         mTestPssMode, isSleeping(), now);
18075             } else if (false && DEBUG_PSS) {
18076                 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18077             }
18078         }
18079         if (app.setProcState != app.curProcState) {
18080             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18081                     "Proc state change of " + app.processName
18082                     + " to " + app.curProcState);
18083             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18084             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18085             if (setImportant && !curImportant) {
18086                 // This app is no longer something we consider important enough to allow to
18087                 // use arbitrary amounts of battery power.  Note
18088                 // its current wake lock time to later know to kill it if
18089                 // it is not behaving well.
18090                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18091                 synchronized (stats) {
18092                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18093                             app.pid, SystemClock.elapsedRealtime());
18094                 }
18095                 app.lastCpuTime = app.curCpuTime;
18096
18097             }
18098             app.setProcState = app.curProcState;
18099             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18100                 app.notCachedSinceIdle = false;
18101             }
18102             if (!doingAll) {
18103                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18104             } else {
18105                 app.procStateChanged = true;
18106             }
18107         }
18108
18109         if (changes != 0) {
18110             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18111             int i = mPendingProcessChanges.size()-1;
18112             ProcessChangeItem item = null;
18113             while (i >= 0) {
18114                 item = mPendingProcessChanges.get(i);
18115                 if (item.pid == app.pid) {
18116                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18117                     break;
18118                 }
18119                 i--;
18120             }
18121             if (i < 0) {
18122                 // No existing item in pending changes; need a new one.
18123                 final int NA = mAvailProcessChanges.size();
18124                 if (NA > 0) {
18125                     item = mAvailProcessChanges.remove(NA-1);
18126                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18127                 } else {
18128                     item = new ProcessChangeItem();
18129                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18130                 }
18131                 item.changes = 0;
18132                 item.pid = app.pid;
18133                 item.uid = app.info.uid;
18134                 if (mPendingProcessChanges.size() == 0) {
18135                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18136                             "*** Enqueueing dispatch processes changed!");
18137                     mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18138                 }
18139                 mPendingProcessChanges.add(item);
18140             }
18141             item.changes |= changes;
18142             item.processState = app.repProcState;
18143             item.foregroundActivities = app.repForegroundActivities;
18144             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18145                     + Integer.toHexString(System.identityHashCode(item))
18146                     + " " + app.toShortString() + ": changes=" + item.changes
18147                     + " procState=" + item.processState
18148                     + " foreground=" + item.foregroundActivities
18149                     + " type=" + app.adjType + " source=" + app.adjSource
18150                     + " target=" + app.adjTarget);
18151         }
18152
18153         return success;
18154     }
18155
18156     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18157         if (proc.thread != null) {
18158             if (proc.baseProcessTracker != null) {
18159                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18160             }
18161             if (proc.repProcState >= 0) {
18162                 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18163                         proc.repProcState);
18164             }
18165         }
18166     }
18167
18168     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18169             ProcessRecord TOP_APP, boolean doingAll, long now) {
18170         if (app.thread == null) {
18171             return false;
18172         }
18173
18174         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18175
18176         return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18177     }
18178
18179     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18180             boolean oomAdj) {
18181         if (isForeground != proc.foregroundServices) {
18182             proc.foregroundServices = isForeground;
18183             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18184                     proc.info.uid);
18185             if (isForeground) {
18186                 if (curProcs == null) {
18187                     curProcs = new ArrayList<ProcessRecord>();
18188                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18189                 }
18190                 if (!curProcs.contains(proc)) {
18191                     curProcs.add(proc);
18192                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18193                             proc.info.packageName, proc.info.uid);
18194                 }
18195             } else {
18196                 if (curProcs != null) {
18197                     if (curProcs.remove(proc)) {
18198                         mBatteryStatsService.noteEvent(
18199                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18200                                 proc.info.packageName, proc.info.uid);
18201                         if (curProcs.size() <= 0) {
18202                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18203                         }
18204                     }
18205                 }
18206             }
18207             if (oomAdj) {
18208                 updateOomAdjLocked();
18209             }
18210         }
18211     }
18212
18213     private final ActivityRecord resumedAppLocked() {
18214         ActivityRecord act = mStackSupervisor.resumedAppLocked();
18215         String pkg;
18216         int uid;
18217         if (act != null) {
18218             pkg = act.packageName;
18219             uid = act.info.applicationInfo.uid;
18220         } else {
18221             pkg = null;
18222             uid = -1;
18223         }
18224         // Has the UID or resumed package name changed?
18225         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18226                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18227             if (mCurResumedPackage != null) {
18228                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18229                         mCurResumedPackage, mCurResumedUid);
18230             }
18231             mCurResumedPackage = pkg;
18232             mCurResumedUid = uid;
18233             if (mCurResumedPackage != null) {
18234                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18235                         mCurResumedPackage, mCurResumedUid);
18236             }
18237         }
18238         return act;
18239     }
18240
18241     final boolean updateOomAdjLocked(ProcessRecord app) {
18242         final ActivityRecord TOP_ACT = resumedAppLocked();
18243         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18244         final boolean wasCached = app.cached;
18245
18246         mAdjSeq++;
18247
18248         // This is the desired cached adjusment we want to tell it to use.
18249         // If our app is currently cached, we know it, and that is it.  Otherwise,
18250         // we don't know it yet, and it needs to now be cached we will then
18251         // need to do a complete oom adj.
18252         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18253                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18254         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18255                 SystemClock.uptimeMillis());
18256         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18257             // Changed to/from cached state, so apps after it in the LRU
18258             // list may also be changed.
18259             updateOomAdjLocked();
18260         }
18261         return success;
18262     }
18263
18264     final void updateOomAdjLocked() {
18265         final ActivityRecord TOP_ACT = resumedAppLocked();
18266         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18267         final long now = SystemClock.uptimeMillis();
18268         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18269         final int N = mLruProcesses.size();
18270
18271         if (false) {
18272             RuntimeException e = new RuntimeException();
18273             e.fillInStackTrace();
18274             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18275         }
18276
18277         mAdjSeq++;
18278         mNewNumServiceProcs = 0;
18279         mNewNumAServiceProcs = 0;
18280
18281         final int emptyProcessLimit;
18282         final int cachedProcessLimit;
18283         if (mProcessLimit <= 0) {
18284             emptyProcessLimit = cachedProcessLimit = 0;
18285         } else if (mProcessLimit == 1) {
18286             emptyProcessLimit = 1;
18287             cachedProcessLimit = 0;
18288         } else {
18289             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18290             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18291         }
18292
18293         // Let's determine how many processes we have running vs.
18294         // how many slots we have for background processes; we may want
18295         // to put multiple processes in a slot of there are enough of
18296         // them.
18297         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18298                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18299         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18300         if (numEmptyProcs > cachedProcessLimit) {
18301             // If there are more empty processes than our limit on cached
18302             // processes, then use the cached process limit for the factor.
18303             // This ensures that the really old empty processes get pushed
18304             // down to the bottom, so if we are running low on memory we will
18305             // have a better chance at keeping around more cached processes
18306             // instead of a gazillion empty processes.
18307             numEmptyProcs = cachedProcessLimit;
18308         }
18309         int emptyFactor = numEmptyProcs/numSlots;
18310         if (emptyFactor < 1) emptyFactor = 1;
18311         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18312         if (cachedFactor < 1) cachedFactor = 1;
18313         int stepCached = 0;
18314         int stepEmpty = 0;
18315         int numCached = 0;
18316         int numEmpty = 0;
18317         int numTrimming = 0;
18318
18319         mNumNonCachedProcs = 0;
18320         mNumCachedHiddenProcs = 0;
18321
18322         // First update the OOM adjustment for each of the
18323         // application processes based on their current state.
18324         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18325         int nextCachedAdj = curCachedAdj+1;
18326         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18327         int nextEmptyAdj = curEmptyAdj+2;
18328         for (int i=N-1; i>=0; i--) {
18329             ProcessRecord app = mLruProcesses.get(i);
18330             if (!app.killedByAm && app.thread != null) {
18331                 app.procStateChanged = false;
18332                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18333
18334                 // If we haven't yet assigned the final cached adj
18335                 // to the process, do that now.
18336                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18337                     switch (app.curProcState) {
18338                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18339                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18340                             // This process is a cached process holding activities...
18341                             // assign it the next cached value for that type, and then
18342                             // step that cached level.
18343                             app.curRawAdj = curCachedAdj;
18344                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18345                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18346                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18347                                     + ")");
18348                             if (curCachedAdj != nextCachedAdj) {
18349                                 stepCached++;
18350                                 if (stepCached >= cachedFactor) {
18351                                     stepCached = 0;
18352                                     curCachedAdj = nextCachedAdj;
18353                                     nextCachedAdj += 2;
18354                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18355                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18356                                     }
18357                                 }
18358                             }
18359                             break;
18360                         default:
18361                             // For everything else, assign next empty cached process
18362                             // level and bump that up.  Note that this means that
18363                             // long-running services that have dropped down to the
18364                             // cached level will be treated as empty (since their process
18365                             // state is still as a service), which is what we want.
18366                             app.curRawAdj = curEmptyAdj;
18367                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18368                             if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18369                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18370                                     + ")");
18371                             if (curEmptyAdj != nextEmptyAdj) {
18372                                 stepEmpty++;
18373                                 if (stepEmpty >= emptyFactor) {
18374                                     stepEmpty = 0;
18375                                     curEmptyAdj = nextEmptyAdj;
18376                                     nextEmptyAdj += 2;
18377                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18378                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18379                                     }
18380                                 }
18381                             }
18382                             break;
18383                     }
18384                 }
18385
18386                 applyOomAdjLocked(app, TOP_APP, true, now);
18387
18388                 // Count the number of process types.
18389                 switch (app.curProcState) {
18390                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18391                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18392                         mNumCachedHiddenProcs++;
18393                         numCached++;
18394                         if (numCached > cachedProcessLimit) {
18395                             app.kill("cached #" + numCached, true);
18396                         }
18397                         break;
18398                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18399                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18400                                 && app.lastActivityTime < oldTime) {
18401                             app.kill("empty for "
18402                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18403                                     / 1000) + "s", true);
18404                         } else {
18405                             numEmpty++;
18406                             if (numEmpty > emptyProcessLimit) {
18407                                 app.kill("empty #" + numEmpty, true);
18408                             }
18409                         }
18410                         break;
18411                     default:
18412                         mNumNonCachedProcs++;
18413                         break;
18414                 }
18415
18416                 if (app.isolated && app.services.size() <= 0) {
18417                     // If this is an isolated process, and there are no
18418                     // services running in it, then the process is no longer
18419                     // needed.  We agressively kill these because we can by
18420                     // definition not re-use the same process again, and it is
18421                     // good to avoid having whatever code was running in them
18422                     // left sitting around after no longer needed.
18423                     app.kill("isolated not needed", true);
18424                 }
18425
18426                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18427                         && !app.killedByAm) {
18428                     numTrimming++;
18429                 }
18430             }
18431         }
18432
18433         mNumServiceProcs = mNewNumServiceProcs;
18434
18435         // Now determine the memory trimming level of background processes.
18436         // Unfortunately we need to start at the back of the list to do this
18437         // properly.  We only do this if the number of background apps we
18438         // are managing to keep around is less than half the maximum we desire;
18439         // if we are keeping a good number around, we'll let them use whatever
18440         // memory they want.
18441         final int numCachedAndEmpty = numCached + numEmpty;
18442         int memFactor;
18443         if (numCached <= ProcessList.TRIM_CACHED_APPS
18444                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18445             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18446                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18447             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18448                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18449             } else {
18450                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18451             }
18452         } else {
18453             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18454         }
18455         // We always allow the memory level to go up (better).  We only allow it to go
18456         // down if we are in a state where that is allowed, *and* the total number of processes
18457         // has gone down since last time.
18458         if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18459                 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18460                 + " last=" + mLastNumProcesses);
18461         if (memFactor > mLastMemoryLevel) {
18462             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18463                 memFactor = mLastMemoryLevel;
18464                 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18465             }
18466         }
18467         mLastMemoryLevel = memFactor;
18468         mLastNumProcesses = mLruProcesses.size();
18469         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18470         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18471         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18472             if (mLowRamStartTime == 0) {
18473                 mLowRamStartTime = now;
18474             }
18475             int step = 0;
18476             int fgTrimLevel;
18477             switch (memFactor) {
18478                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18479                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18480                     break;
18481                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
18482                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18483                     break;
18484                 default:
18485                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18486                     break;
18487             }
18488             int factor = numTrimming/3;
18489             int minFactor = 2;
18490             if (mHomeProcess != null) minFactor++;
18491             if (mPreviousProcess != null) minFactor++;
18492             if (factor < minFactor) factor = minFactor;
18493             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18494             for (int i=N-1; i>=0; i--) {
18495                 ProcessRecord app = mLruProcesses.get(i);
18496                 if (allChanged || app.procStateChanged) {
18497                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
18498                     app.procStateChanged = false;
18499                 }
18500                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18501                         && !app.killedByAm) {
18502                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
18503                         try {
18504                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18505                                     "Trimming memory of " + app.processName
18506                                     + " to " + curLevel);
18507                             app.thread.scheduleTrimMemory(curLevel);
18508                         } catch (RemoteException e) {
18509                         }
18510                         if (false) {
18511                             // For now we won't do this; our memory trimming seems
18512                             // to be good enough at this point that destroying
18513                             // activities causes more harm than good.
18514                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18515                                     && app != mHomeProcess && app != mPreviousProcess) {
18516                                 // Need to do this on its own message because the stack may not
18517                                 // be in a consistent state at this point.
18518                                 // For these apps we will also finish their activities
18519                                 // to help them free memory.
18520                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18521                             }
18522                         }
18523                     }
18524                     app.trimMemoryLevel = curLevel;
18525                     step++;
18526                     if (step >= factor) {
18527                         step = 0;
18528                         switch (curLevel) {
18529                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18530                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18531                                 break;
18532                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18533                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18534                                 break;
18535                         }
18536                     }
18537                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18538                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18539                             && app.thread != null) {
18540                         try {
18541                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18542                                     "Trimming memory of heavy-weight " + app.processName
18543                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18544                             app.thread.scheduleTrimMemory(
18545                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18546                         } catch (RemoteException e) {
18547                         }
18548                     }
18549                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18550                 } else {
18551                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18552                             || app.systemNoUi) && app.pendingUiClean) {
18553                         // If this application is now in the background and it
18554                         // had done UI, then give it the special trim level to
18555                         // have it free UI resources.
18556                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18557                         if (app.trimMemoryLevel < level && app.thread != null) {
18558                             try {
18559                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18560                                         "Trimming memory of bg-ui " + app.processName
18561                                         + " to " + level);
18562                                 app.thread.scheduleTrimMemory(level);
18563                             } catch (RemoteException e) {
18564                             }
18565                         }
18566                         app.pendingUiClean = false;
18567                     }
18568                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18569                         try {
18570                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18571                                     "Trimming memory of fg " + app.processName
18572                                     + " to " + fgTrimLevel);
18573                             app.thread.scheduleTrimMemory(fgTrimLevel);
18574                         } catch (RemoteException e) {
18575                         }
18576                     }
18577                     app.trimMemoryLevel = fgTrimLevel;
18578                 }
18579             }
18580         } else {
18581             if (mLowRamStartTime != 0) {
18582                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18583                 mLowRamStartTime = 0;
18584             }
18585             for (int i=N-1; i>=0; i--) {
18586                 ProcessRecord app = mLruProcesses.get(i);
18587                 if (allChanged || app.procStateChanged) {
18588                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
18589                     app.procStateChanged = false;
18590                 }
18591                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18592                         || app.systemNoUi) && app.pendingUiClean) {
18593                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18594                             && app.thread != null) {
18595                         try {
18596                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18597                                     "Trimming memory of ui hidden " + app.processName
18598                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18599                             app.thread.scheduleTrimMemory(
18600                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18601                         } catch (RemoteException e) {
18602                         }
18603                     }
18604                     app.pendingUiClean = false;
18605                 }
18606                 app.trimMemoryLevel = 0;
18607             }
18608         }
18609
18610         if (mAlwaysFinishActivities) {
18611             // Need to do this on its own message because the stack may not
18612             // be in a consistent state at this point.
18613             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18614         }
18615
18616         if (allChanged) {
18617             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18618         }
18619
18620         if (mProcessStats.shouldWriteNowLocked(now)) {
18621             mHandler.post(new Runnable() {
18622                 @Override public void run() {
18623                     synchronized (ActivityManagerService.this) {
18624                         mProcessStats.writeStateAsyncLocked();
18625                     }
18626                 }
18627             });
18628         }
18629
18630         if (DEBUG_OOM_ADJ) {
18631             if (false) {
18632                 RuntimeException here = new RuntimeException("here");
18633                 here.fillInStackTrace();
18634                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18635             } else {
18636                 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18637             }
18638         }
18639     }
18640
18641     final void trimApplications() {
18642         synchronized (this) {
18643             int i;
18644
18645             // First remove any unused application processes whose package
18646             // has been removed.
18647             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18648                 final ProcessRecord app = mRemovedProcesses.get(i);
18649                 if (app.activities.size() == 0
18650                         && app.curReceiver == null && app.services.size() == 0) {
18651                     Slog.i(
18652                         TAG, "Exiting empty application process "
18653                         + app.processName + " ("
18654                         + (app.thread != null ? app.thread.asBinder() : null)
18655                         + ")\n");
18656                     if (app.pid > 0 && app.pid != MY_PID) {
18657                         app.kill("empty", false);
18658                     } else {
18659                         try {
18660                             app.thread.scheduleExit();
18661                         } catch (Exception e) {
18662                             // Ignore exceptions.
18663                         }
18664                     }
18665                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
18666                     mRemovedProcesses.remove(i);
18667
18668                     if (app.persistent) {
18669                         addAppLocked(app.info, false, null /* ABI override */);
18670                     }
18671                 }
18672             }
18673
18674             // Now update the oom adj for all processes.
18675             updateOomAdjLocked();
18676         }
18677     }
18678
18679     /** This method sends the specified signal to each of the persistent apps */
18680     public void signalPersistentProcesses(int sig) throws RemoteException {
18681         if (sig != Process.SIGNAL_USR1) {
18682             throw new SecurityException("Only SIGNAL_USR1 is allowed");
18683         }
18684
18685         synchronized (this) {
18686             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18687                     != PackageManager.PERMISSION_GRANTED) {
18688                 throw new SecurityException("Requires permission "
18689                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18690             }
18691
18692             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18693                 ProcessRecord r = mLruProcesses.get(i);
18694                 if (r.thread != null && r.persistent) {
18695                     Process.sendSignal(r.pid, sig);
18696                 }
18697             }
18698         }
18699     }
18700
18701     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18702         if (proc == null || proc == mProfileProc) {
18703             proc = mProfileProc;
18704             profileType = mProfileType;
18705             clearProfilerLocked();
18706         }
18707         if (proc == null) {
18708             return;
18709         }
18710         try {
18711             proc.thread.profilerControl(false, null, profileType);
18712         } catch (RemoteException e) {
18713             throw new IllegalStateException("Process disappeared");
18714         }
18715     }
18716
18717     private void clearProfilerLocked() {
18718         if (mProfileFd != null) {
18719             try {
18720                 mProfileFd.close();
18721             } catch (IOException e) {
18722             }
18723         }
18724         mProfileApp = null;
18725         mProfileProc = null;
18726         mProfileFile = null;
18727         mProfileType = 0;
18728         mAutoStopProfiler = false;
18729         mSamplingInterval = 0;
18730     }
18731
18732     public boolean profileControl(String process, int userId, boolean start,
18733             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18734
18735         try {
18736             synchronized (this) {
18737                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18738                 // its own permission.
18739                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18740                         != PackageManager.PERMISSION_GRANTED) {
18741                     throw new SecurityException("Requires permission "
18742                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18743                 }
18744
18745                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18746                     throw new IllegalArgumentException("null profile info or fd");
18747                 }
18748
18749                 ProcessRecord proc = null;
18750                 if (process != null) {
18751                     proc = findProcessLocked(process, userId, "profileControl");
18752                 }
18753
18754                 if (start && (proc == null || proc.thread == null)) {
18755                     throw new IllegalArgumentException("Unknown process: " + process);
18756                 }
18757
18758                 if (start) {
18759                     stopProfilerLocked(null, 0);
18760                     setProfileApp(proc.info, proc.processName, profilerInfo);
18761                     mProfileProc = proc;
18762                     mProfileType = profileType;
18763                     ParcelFileDescriptor fd = profilerInfo.profileFd;
18764                     try {
18765                         fd = fd.dup();
18766                     } catch (IOException e) {
18767                         fd = null;
18768                     }
18769                     profilerInfo.profileFd = fd;
18770                     proc.thread.profilerControl(start, profilerInfo, profileType);
18771                     fd = null;
18772                     mProfileFd = null;
18773                 } else {
18774                     stopProfilerLocked(proc, profileType);
18775                     if (profilerInfo != null && profilerInfo.profileFd != null) {
18776                         try {
18777                             profilerInfo.profileFd.close();
18778                         } catch (IOException e) {
18779                         }
18780                     }
18781                 }
18782
18783                 return true;
18784             }
18785         } catch (RemoteException e) {
18786             throw new IllegalStateException("Process disappeared");
18787         } finally {
18788             if (profilerInfo != null && profilerInfo.profileFd != null) {
18789                 try {
18790                     profilerInfo.profileFd.close();
18791                 } catch (IOException e) {
18792                 }
18793             }
18794         }
18795     }
18796
18797     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18798         userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18799                 userId, true, ALLOW_FULL_ONLY, callName, null);
18800         ProcessRecord proc = null;
18801         try {
18802             int pid = Integer.parseInt(process);
18803             synchronized (mPidsSelfLocked) {
18804                 proc = mPidsSelfLocked.get(pid);
18805             }
18806         } catch (NumberFormatException e) {
18807         }
18808
18809         if (proc == null) {
18810             ArrayMap<String, SparseArray<ProcessRecord>> all
18811                     = mProcessNames.getMap();
18812             SparseArray<ProcessRecord> procs = all.get(process);
18813             if (procs != null && procs.size() > 0) {
18814                 proc = procs.valueAt(0);
18815                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18816                     for (int i=1; i<procs.size(); i++) {
18817                         ProcessRecord thisProc = procs.valueAt(i);
18818                         if (thisProc.userId == userId) {
18819                             proc = thisProc;
18820                             break;
18821                         }
18822                     }
18823                 }
18824             }
18825         }
18826
18827         return proc;
18828     }
18829
18830     public boolean dumpHeap(String process, int userId, boolean managed,
18831             String path, ParcelFileDescriptor fd) throws RemoteException {
18832
18833         try {
18834             synchronized (this) {
18835                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18836                 // its own permission (same as profileControl).
18837                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18838                         != PackageManager.PERMISSION_GRANTED) {
18839                     throw new SecurityException("Requires permission "
18840                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18841                 }
18842
18843                 if (fd == null) {
18844                     throw new IllegalArgumentException("null fd");
18845                 }
18846
18847                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18848                 if (proc == null || proc.thread == null) {
18849                     throw new IllegalArgumentException("Unknown process: " + process);
18850                 }
18851
18852                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18853                 if (!isDebuggable) {
18854                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18855                         throw new SecurityException("Process not debuggable: " + proc);
18856                     }
18857                 }
18858
18859                 proc.thread.dumpHeap(managed, path, fd);
18860                 fd = null;
18861                 return true;
18862             }
18863         } catch (RemoteException e) {
18864             throw new IllegalStateException("Process disappeared");
18865         } finally {
18866             if (fd != null) {
18867                 try {
18868                     fd.close();
18869                 } catch (IOException e) {
18870                 }
18871             }
18872         }
18873     }
18874
18875     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18876     public void monitor() {
18877         synchronized (this) { }
18878     }
18879
18880     void onCoreSettingsChange(Bundle settings) {
18881         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18882             ProcessRecord processRecord = mLruProcesses.get(i);
18883             try {
18884                 if (processRecord.thread != null) {
18885                     processRecord.thread.setCoreSettings(settings);
18886                 }
18887             } catch (RemoteException re) {
18888                 /* ignore */
18889             }
18890         }
18891     }
18892
18893     // Multi-user methods
18894
18895     /**
18896      * Start user, if its not already running, but don't bring it to foreground.
18897      */
18898     @Override
18899     public boolean startUserInBackground(final int userId) {
18900         return startUser(userId, /* foreground */ false);
18901     }
18902
18903     /**
18904      * Start user, if its not already running, and bring it to foreground.
18905      */
18906     boolean startUserInForeground(final int userId, Dialog dlg) {
18907         boolean result = startUser(userId, /* foreground */ true);
18908         dlg.dismiss();
18909         return result;
18910     }
18911
18912     /**
18913      * Refreshes the list of users related to the current user when either a
18914      * user switch happens or when a new related user is started in the
18915      * background.
18916      */
18917     private void updateCurrentProfileIdsLocked() {
18918         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18919                 mCurrentUserId, false /* enabledOnly */);
18920         int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18921         for (int i = 0; i < currentProfileIds.length; i++) {
18922             currentProfileIds[i] = profiles.get(i).id;
18923         }
18924         mCurrentProfileIds = currentProfileIds;
18925
18926         synchronized (mUserProfileGroupIdsSelfLocked) {
18927             mUserProfileGroupIdsSelfLocked.clear();
18928             final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18929             for (int i = 0; i < users.size(); i++) {
18930                 UserInfo user = users.get(i);
18931                 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18932                     mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18933                 }
18934             }
18935         }
18936     }
18937
18938     private Set getProfileIdsLocked(int userId) {
18939         Set userIds = new HashSet<Integer>();
18940         final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18941                 userId, false /* enabledOnly */);
18942         for (UserInfo user : profiles) {
18943             userIds.add(Integer.valueOf(user.id));
18944         }
18945         return userIds;
18946     }
18947
18948     @Override
18949     public boolean switchUser(final int userId) {
18950         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18951         String userName;
18952         synchronized (this) {
18953             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18954             if (userInfo == null) {
18955                 Slog.w(TAG, "No user info for user #" + userId);
18956                 return false;
18957             }
18958             if (userInfo.isManagedProfile()) {
18959                 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18960                 return false;
18961             }
18962             userName = userInfo.name;
18963             mTargetUserId = userId;
18964         }
18965         mHandler.removeMessages(START_USER_SWITCH_MSG);
18966         mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18967         return true;
18968     }
18969
18970     private void showUserSwitchDialog(int userId, String userName) {
18971         // The dialog will show and then initiate the user switch by calling startUserInForeground
18972         Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18973                 true /* above system */);
18974         d.show();
18975     }
18976
18977     private boolean startUser(final int userId, final boolean foreground) {
18978         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18979                 != PackageManager.PERMISSION_GRANTED) {
18980             String msg = "Permission Denial: switchUser() from pid="
18981                     + Binder.getCallingPid()
18982                     + ", uid=" + Binder.getCallingUid()
18983                     + " requires " + INTERACT_ACROSS_USERS_FULL;
18984             Slog.w(TAG, msg);
18985             throw new SecurityException(msg);
18986         }
18987
18988         if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18989
18990         final long ident = Binder.clearCallingIdentity();
18991         try {
18992             synchronized (this) {
18993                 final int oldUserId = mCurrentUserId;
18994                 if (oldUserId == userId) {
18995                     return true;
18996                 }
18997
18998                 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18999
19000                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19001                 if (userInfo == null) {
19002                     Slog.w(TAG, "No user info for user #" + userId);
19003                     return false;
19004                 }
19005                 if (foreground && userInfo.isManagedProfile()) {
19006                     Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19007                     return false;
19008                 }
19009
19010                 if (foreground) {
19011                     mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19012                             R.anim.screen_user_enter);
19013                 }
19014
19015                 boolean needStart = false;
19016
19017                 // If the user we are switching to is not currently started, then
19018                 // we need to start it now.
19019                 if (mStartedUsers.get(userId) == null) {
19020                     mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19021                     updateStartedUserArrayLocked();
19022                     needStart = true;
19023                 }
19024
19025                 final Integer userIdInt = Integer.valueOf(userId);
19026                 mUserLru.remove(userIdInt);
19027                 mUserLru.add(userIdInt);
19028
19029                 if (foreground) {
19030                     mCurrentUserId = userId;
19031                     mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19032                     updateCurrentProfileIdsLocked();
19033                     mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19034                     // Once the internal notion of the active user has switched, we lock the device
19035                     // with the option to show the user switcher on the keyguard.
19036                     mWindowManager.lockNow(null);
19037                 } else {
19038                     final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19039                     updateCurrentProfileIdsLocked();
19040                     mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19041                     mUserLru.remove(currentUserIdInt);
19042                     mUserLru.add(currentUserIdInt);
19043                 }
19044
19045                 final UserStartedState uss = mStartedUsers.get(userId);
19046
19047                 // Make sure user is in the started state.  If it is currently
19048                 // stopping, we need to knock that off.
19049                 if (uss.mState == UserStartedState.STATE_STOPPING) {
19050                     // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19051                     // so we can just fairly silently bring the user back from
19052                     // the almost-dead.
19053                     uss.mState = UserStartedState.STATE_RUNNING;
19054                     updateStartedUserArrayLocked();
19055                     needStart = true;
19056                 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19057                     // This means ACTION_SHUTDOWN has been sent, so we will
19058                     // need to treat this as a new boot of the user.
19059                     uss.mState = UserStartedState.STATE_BOOTING;
19060                     updateStartedUserArrayLocked();
19061                     needStart = true;
19062                 }
19063
19064                 if (uss.mState == UserStartedState.STATE_BOOTING) {
19065                     // Booting up a new user, need to tell system services about it.
19066                     // Note that this is on the same handler as scheduling of broadcasts,
19067                     // which is important because it needs to go first.
19068                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19069                 }
19070
19071                 if (foreground) {
19072                     mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19073                             oldUserId));
19074                     mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19075                     mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19076                     mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19077                             oldUserId, userId, uss));
19078                     mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19079                             oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19080                 }
19081
19082                 if (needStart) {
19083                     // Send USER_STARTED broadcast
19084                     Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19085                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19086                             | Intent.FLAG_RECEIVER_FOREGROUND);
19087                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19088                     broadcastIntentLocked(null, null, intent,
19089                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19090                             false, false, MY_PID, Process.SYSTEM_UID, userId);
19091                 }
19092
19093                 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19094                     if (userId != UserHandle.USER_OWNER) {
19095                         Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19096                         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19097                         broadcastIntentLocked(null, null, intent, null,
19098                                 new IIntentReceiver.Stub() {
19099                                     public void performReceive(Intent intent, int resultCode,
19100                                             String data, Bundle extras, boolean ordered,
19101                                             boolean sticky, int sendingUser) {
19102                                         onUserInitialized(uss, foreground, oldUserId, userId);
19103                                     }
19104                                 }, 0, null, null, null, AppOpsManager.OP_NONE,
19105                                 true, false, MY_PID, Process.SYSTEM_UID,
19106                                 userId);
19107                         uss.initializing = true;
19108                     } else {
19109                         getUserManagerLocked().makeInitialized(userInfo.id);
19110                     }
19111                 }
19112
19113                 if (foreground) {
19114                     if (!uss.initializing) {
19115                         moveUserToForeground(uss, oldUserId, userId);
19116                     }
19117                 } else {
19118                     mStackSupervisor.startBackgroundUserLocked(userId, uss);
19119                 }
19120
19121                 if (needStart) {
19122                     Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19123                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19124                     intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19125                     broadcastIntentLocked(null, null, intent,
19126                             null, new IIntentReceiver.Stub() {
19127                                 @Override
19128                                 public void performReceive(Intent intent, int resultCode, String data,
19129                                         Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19130                                         throws RemoteException {
19131                                 }
19132                             }, 0, null, null,
19133                             INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19134                             true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19135                 }
19136             }
19137         } finally {
19138             Binder.restoreCallingIdentity(ident);
19139         }
19140
19141         return true;
19142     }
19143
19144     void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19145         long ident = Binder.clearCallingIdentity();
19146         try {
19147             Intent intent;
19148             if (oldUserId >= 0) {
19149                 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19150                 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19151                 int count = profiles.size();
19152                 for (int i = 0; i < count; i++) {
19153                     int profileUserId = profiles.get(i).id;
19154                     intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19155                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19156                             | Intent.FLAG_RECEIVER_FOREGROUND);
19157                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19158                     broadcastIntentLocked(null, null, intent,
19159                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19160                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19161                 }
19162             }
19163             if (newUserId >= 0) {
19164                 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19165                 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19166                 int count = profiles.size();
19167                 for (int i = 0; i < count; i++) {
19168                     int profileUserId = profiles.get(i).id;
19169                     intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19170                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19171                             | Intent.FLAG_RECEIVER_FOREGROUND);
19172                     intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19173                     broadcastIntentLocked(null, null, intent,
19174                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19175                             false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19176                 }
19177                 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19178                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19179                         | Intent.FLAG_RECEIVER_FOREGROUND);
19180                 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19181                 broadcastIntentLocked(null, null, intent,
19182                         null, null, 0, null, null,
19183                         android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19184                         false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19185             }
19186         } finally {
19187             Binder.restoreCallingIdentity(ident);
19188         }
19189     }
19190
19191     void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19192             final int newUserId) {
19193         final int N = mUserSwitchObservers.beginBroadcast();
19194         if (N > 0) {
19195             final IRemoteCallback callback = new IRemoteCallback.Stub() {
19196                 int mCount = 0;
19197                 @Override
19198                 public void sendResult(Bundle data) throws RemoteException {
19199                     synchronized (ActivityManagerService.this) {
19200                         if (mCurUserSwitchCallback == this) {
19201                             mCount++;
19202                             if (mCount == N) {
19203                                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19204                             }
19205                         }
19206                     }
19207                 }
19208             };
19209             synchronized (this) {
19210                 uss.switching = true;
19211                 mCurUserSwitchCallback = callback;
19212             }
19213             for (int i=0; i<N; i++) {
19214                 try {
19215                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19216                             newUserId, callback);
19217                 } catch (RemoteException e) {
19218                 }
19219             }
19220         } else {
19221             synchronized (this) {
19222                 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19223             }
19224         }
19225         mUserSwitchObservers.finishBroadcast();
19226     }
19227
19228     void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19229         synchronized (this) {
19230             Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19231             sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19232         }
19233     }
19234
19235     void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19236         mCurUserSwitchCallback = null;
19237         mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19238         mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19239                 oldUserId, newUserId, uss));
19240     }
19241
19242     void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19243         synchronized (this) {
19244             if (foreground) {
19245                 moveUserToForeground(uss, oldUserId, newUserId);
19246             }
19247         }
19248
19249         completeSwitchAndInitalize(uss, newUserId, true, false);
19250     }
19251
19252     void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19253         boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19254         if (homeInFront) {
19255             startHomeActivityLocked(newUserId, "moveUserToFroreground");
19256         } else {
19257             mStackSupervisor.resumeTopActivitiesLocked();
19258         }
19259         EventLogTags.writeAmSwitchUser(newUserId);
19260         getUserManagerLocked().userForeground(newUserId);
19261         sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19262     }
19263
19264     void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19265         completeSwitchAndInitalize(uss, newUserId, false, true);
19266     }
19267
19268     void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19269             boolean clearInitializing, boolean clearSwitching) {
19270         boolean unfrozen = false;
19271         synchronized (this) {
19272             if (clearInitializing) {
19273                 uss.initializing = false;
19274                 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19275             }
19276             if (clearSwitching) {
19277                 uss.switching = false;
19278             }
19279             if (!uss.switching && !uss.initializing) {
19280                 mWindowManager.stopFreezingScreen();
19281                 unfrozen = true;
19282             }
19283         }
19284         if (unfrozen) {
19285             final int N = mUserSwitchObservers.beginBroadcast();
19286             for (int i=0; i<N; i++) {
19287                 try {
19288                     mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19289                 } catch (RemoteException e) {
19290                 }
19291             }
19292             mUserSwitchObservers.finishBroadcast();
19293         }
19294         stopGuestUserIfBackground();
19295     }
19296
19297     /**
19298      * Stops the guest user if it has gone to the background.
19299      */
19300     private void stopGuestUserIfBackground() {
19301         synchronized (this) {
19302             final int num = mUserLru.size();
19303             for (int i = 0; i < num; i++) {
19304                 Integer oldUserId = mUserLru.get(i);
19305                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19306                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19307                         || oldUss.mState == UserStartedState.STATE_STOPPING
19308                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19309                     continue;
19310                 }
19311                 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19312                 if (userInfo.isGuest()) {
19313                     // This is a user to be stopped.
19314                     stopUserLocked(oldUserId, null);
19315                     break;
19316                 }
19317             }
19318         }
19319     }
19320
19321     void scheduleStartProfilesLocked() {
19322         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19323             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19324                     DateUtils.SECOND_IN_MILLIS);
19325         }
19326     }
19327
19328     void startProfilesLocked() {
19329         if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19330         List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19331                 mCurrentUserId, false /* enabledOnly */);
19332         List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19333         for (UserInfo user : profiles) {
19334             if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19335                     && user.id != mCurrentUserId) {
19336                 toStart.add(user);
19337             }
19338         }
19339         final int n = toStart.size();
19340         int i = 0;
19341         for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19342             startUserInBackground(toStart.get(i).id);
19343         }
19344         if (i < n) {
19345             Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19346         }
19347     }
19348
19349     void finishUserBoot(UserStartedState uss) {
19350         synchronized (this) {
19351             if (uss.mState == UserStartedState.STATE_BOOTING
19352                     && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19353                 uss.mState = UserStartedState.STATE_RUNNING;
19354                 final int userId = uss.mHandle.getIdentifier();
19355                 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19356                 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19357                 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19358                 broadcastIntentLocked(null, null, intent,
19359                         null, null, 0, null, null,
19360                         android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19361                         true, false, MY_PID, Process.SYSTEM_UID, userId);
19362             }
19363         }
19364     }
19365
19366     void finishUserSwitch(UserStartedState uss) {
19367         synchronized (this) {
19368             finishUserBoot(uss);
19369
19370             startProfilesLocked();
19371
19372             int num = mUserLru.size();
19373             int i = 0;
19374             while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19375                 Integer oldUserId = mUserLru.get(i);
19376                 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19377                 if (oldUss == null) {
19378                     // Shouldn't happen, but be sane if it does.
19379                     mUserLru.remove(i);
19380                     num--;
19381                     continue;
19382                 }
19383                 if (oldUss.mState == UserStartedState.STATE_STOPPING
19384                         || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19385                     // This user is already stopping, doesn't count.
19386                     num--;
19387                     i++;
19388                     continue;
19389                 }
19390                 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19391                     // Owner and current can't be stopped, but count as running.
19392                     i++;
19393                     continue;
19394                 }
19395                 // This is a user to be stopped.
19396                 stopUserLocked(oldUserId, null);
19397                 num--;
19398                 i++;
19399             }
19400         }
19401     }
19402
19403     @Override
19404     public int stopUser(final int userId, final IStopUserCallback callback) {
19405         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19406                 != PackageManager.PERMISSION_GRANTED) {
19407             String msg = "Permission Denial: switchUser() from pid="
19408                     + Binder.getCallingPid()
19409                     + ", uid=" + Binder.getCallingUid()
19410                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19411             Slog.w(TAG, msg);
19412             throw new SecurityException(msg);
19413         }
19414         if (userId <= 0) {
19415             throw new IllegalArgumentException("Can't stop primary user " + userId);
19416         }
19417         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19418         synchronized (this) {
19419             return stopUserLocked(userId, callback);
19420         }
19421     }
19422
19423     private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19424         if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19425         if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19426             return ActivityManager.USER_OP_IS_CURRENT;
19427         }
19428
19429         final UserStartedState uss = mStartedUsers.get(userId);
19430         if (uss == null) {
19431             // User is not started, nothing to do...  but we do need to
19432             // callback if requested.
19433             if (callback != null) {
19434                 mHandler.post(new Runnable() {
19435                     @Override
19436                     public void run() {
19437                         try {
19438                             callback.userStopped(userId);
19439                         } catch (RemoteException e) {
19440                         }
19441                     }
19442                 });
19443             }
19444             return ActivityManager.USER_OP_SUCCESS;
19445         }
19446
19447         if (callback != null) {
19448             uss.mStopCallbacks.add(callback);
19449         }
19450
19451         if (uss.mState != UserStartedState.STATE_STOPPING
19452                 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19453             uss.mState = UserStartedState.STATE_STOPPING;
19454             updateStartedUserArrayLocked();
19455
19456             long ident = Binder.clearCallingIdentity();
19457             try {
19458                 // We are going to broadcast ACTION_USER_STOPPING and then
19459                 // once that is done send a final ACTION_SHUTDOWN and then
19460                 // stop the user.
19461                 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19462                 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19463                 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19464                 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19465                 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19466                 // This is the result receiver for the final shutdown broadcast.
19467                 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19468                     @Override
19469                     public void performReceive(Intent intent, int resultCode, String data,
19470                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19471                         finishUserStop(uss);
19472                     }
19473                 };
19474                 // This is the result receiver for the initial stopping broadcast.
19475                 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19476                     @Override
19477                     public void performReceive(Intent intent, int resultCode, String data,
19478                             Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19479                         // On to the next.
19480                         synchronized (ActivityManagerService.this) {
19481                             if (uss.mState != UserStartedState.STATE_STOPPING) {
19482                                 // Whoops, we are being started back up.  Abort, abort!
19483                                 return;
19484                             }
19485                             uss.mState = UserStartedState.STATE_SHUTDOWN;
19486                         }
19487                         mBatteryStatsService.noteEvent(
19488                                 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19489                                 Integer.toString(userId), userId);
19490                         mSystemServiceManager.stopUser(userId);
19491                         broadcastIntentLocked(null, null, shutdownIntent,
19492                                 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19493                                 true, false, MY_PID, Process.SYSTEM_UID, userId);
19494                     }
19495                 };
19496                 // Kick things off.
19497                 broadcastIntentLocked(null, null, stoppingIntent,
19498                         null, stoppingReceiver, 0, null, null,
19499                         INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19500                         true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19501             } finally {
19502                 Binder.restoreCallingIdentity(ident);
19503             }
19504         }
19505
19506         return ActivityManager.USER_OP_SUCCESS;
19507     }
19508
19509     void finishUserStop(UserStartedState uss) {
19510         final int userId = uss.mHandle.getIdentifier();
19511         boolean stopped;
19512         ArrayList<IStopUserCallback> callbacks;
19513         synchronized (this) {
19514             callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19515             if (mStartedUsers.get(userId) != uss) {
19516                 stopped = false;
19517             } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19518                 stopped = false;
19519             } else {
19520                 stopped = true;
19521                 // User can no longer run.
19522                 mStartedUsers.remove(userId);
19523                 mUserLru.remove(Integer.valueOf(userId));
19524                 updateStartedUserArrayLocked();
19525
19526                 // Clean up all state and processes associated with the user.
19527                 // Kill all the processes for the user.
19528                 forceStopUserLocked(userId, "finish user");
19529             }
19530
19531             // Explicitly remove the old information in mRecentTasks.
19532             removeRecentTasksForUserLocked(userId);
19533         }
19534
19535         for (int i=0; i<callbacks.size(); i++) {
19536             try {
19537                 if (stopped) callbacks.get(i).userStopped(userId);
19538                 else callbacks.get(i).userStopAborted(userId);
19539             } catch (RemoteException e) {
19540             }
19541         }
19542
19543         if (stopped) {
19544             mSystemServiceManager.cleanupUser(userId);
19545             synchronized (this) {
19546                 mStackSupervisor.removeUserLocked(userId);
19547             }
19548         }
19549     }
19550
19551     @Override
19552     public UserInfo getCurrentUser() {
19553         if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19554                 != PackageManager.PERMISSION_GRANTED) && (
19555                 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19556                 != PackageManager.PERMISSION_GRANTED)) {
19557             String msg = "Permission Denial: getCurrentUser() from pid="
19558                     + Binder.getCallingPid()
19559                     + ", uid=" + Binder.getCallingUid()
19560                     + " requires " + INTERACT_ACROSS_USERS;
19561             Slog.w(TAG, msg);
19562             throw new SecurityException(msg);
19563         }
19564         synchronized (this) {
19565             int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19566             return getUserManagerLocked().getUserInfo(userId);
19567         }
19568     }
19569
19570     int getCurrentUserIdLocked() {
19571         return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19572     }
19573
19574     @Override
19575     public boolean isUserRunning(int userId, boolean orStopped) {
19576         if (checkCallingPermission(INTERACT_ACROSS_USERS)
19577                 != PackageManager.PERMISSION_GRANTED) {
19578             String msg = "Permission Denial: isUserRunning() from pid="
19579                     + Binder.getCallingPid()
19580                     + ", uid=" + Binder.getCallingUid()
19581                     + " requires " + INTERACT_ACROSS_USERS;
19582             Slog.w(TAG, msg);
19583             throw new SecurityException(msg);
19584         }
19585         synchronized (this) {
19586             return isUserRunningLocked(userId, orStopped);
19587         }
19588     }
19589
19590     boolean isUserRunningLocked(int userId, boolean orStopped) {
19591         UserStartedState state = mStartedUsers.get(userId);
19592         if (state == null) {
19593             return false;
19594         }
19595         if (orStopped) {
19596             return true;
19597         }
19598         return state.mState != UserStartedState.STATE_STOPPING
19599                 && state.mState != UserStartedState.STATE_SHUTDOWN;
19600     }
19601
19602     @Override
19603     public int[] getRunningUserIds() {
19604         if (checkCallingPermission(INTERACT_ACROSS_USERS)
19605                 != PackageManager.PERMISSION_GRANTED) {
19606             String msg = "Permission Denial: isUserRunning() from pid="
19607                     + Binder.getCallingPid()
19608                     + ", uid=" + Binder.getCallingUid()
19609                     + " requires " + INTERACT_ACROSS_USERS;
19610             Slog.w(TAG, msg);
19611             throw new SecurityException(msg);
19612         }
19613         synchronized (this) {
19614             return mStartedUserArray;
19615         }
19616     }
19617
19618     private void updateStartedUserArrayLocked() {
19619         int num = 0;
19620         for (int i=0; i<mStartedUsers.size();  i++) {
19621             UserStartedState uss = mStartedUsers.valueAt(i);
19622             // This list does not include stopping users.
19623             if (uss.mState != UserStartedState.STATE_STOPPING
19624                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19625                 num++;
19626             }
19627         }
19628         mStartedUserArray = new int[num];
19629         num = 0;
19630         for (int i=0; i<mStartedUsers.size();  i++) {
19631             UserStartedState uss = mStartedUsers.valueAt(i);
19632             if (uss.mState != UserStartedState.STATE_STOPPING
19633                     && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19634                 mStartedUserArray[num] = mStartedUsers.keyAt(i);
19635                 num++;
19636             }
19637         }
19638     }
19639
19640     @Override
19641     public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19642         if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19643                 != PackageManager.PERMISSION_GRANTED) {
19644             String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19645                     + Binder.getCallingPid()
19646                     + ", uid=" + Binder.getCallingUid()
19647                     + " requires " + INTERACT_ACROSS_USERS_FULL;
19648             Slog.w(TAG, msg);
19649             throw new SecurityException(msg);
19650         }
19651
19652         mUserSwitchObservers.register(observer);
19653     }
19654
19655     @Override
19656     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19657         mUserSwitchObservers.unregister(observer);
19658     }
19659
19660     private boolean userExists(int userId) {
19661         if (userId == 0) {
19662             return true;
19663         }
19664         UserManagerService ums = getUserManagerLocked();
19665         return ums != null ? (ums.getUserInfo(userId) != null) : false;
19666     }
19667
19668     int[] getUsersLocked() {
19669         UserManagerService ums = getUserManagerLocked();
19670         return ums != null ? ums.getUserIds() : new int[] { 0 };
19671     }
19672
19673     UserManagerService getUserManagerLocked() {
19674         if (mUserManager == null) {
19675             IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19676             mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19677         }
19678         return mUserManager;
19679     }
19680
19681     private int applyUserId(int uid, int userId) {
19682         return UserHandle.getUid(userId, uid);
19683     }
19684
19685     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19686         if (info == null) return null;
19687         ApplicationInfo newInfo = new ApplicationInfo(info);
19688         newInfo.uid = applyUserId(info.uid, userId);
19689         newInfo.dataDir = USER_DATA_DIR + userId + "/"
19690                 + info.packageName;
19691         return newInfo;
19692     }
19693
19694     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19695         if (aInfo == null
19696                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19697             return aInfo;
19698         }
19699
19700         ActivityInfo info = new ActivityInfo(aInfo);
19701         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19702         return info;
19703     }
19704
19705     private final class LocalService extends ActivityManagerInternal {
19706         @Override
19707         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
19708                 int targetUserId) {
19709             synchronized (ActivityManagerService.this) {
19710                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
19711                         targetPkg, intent, null, targetUserId);
19712             }
19713         }
19714
19715         @Override
19716         public String checkContentProviderAccess(String authority, int userId) {
19717             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
19718         }
19719
19720         @Override
19721         public void onWakefulnessChanged(int wakefulness) {
19722             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19723         }
19724
19725         @Override
19726         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19727                 String processName, String abiOverride, int uid, Runnable crashHandler) {
19728             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19729                     processName, abiOverride, uid, crashHandler);
19730         }
19731     }
19732
19733     /**
19734      * An implementation of IAppTask, that allows an app to manage its own tasks via
19735      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19736      * only the process that calls getAppTasks() can call the AppTask methods.
19737      */
19738     class AppTaskImpl extends IAppTask.Stub {
19739         private int mTaskId;
19740         private int mCallingUid;
19741
19742         public AppTaskImpl(int taskId, int callingUid) {
19743             mTaskId = taskId;
19744             mCallingUid = callingUid;
19745         }
19746
19747         private void checkCaller() {
19748             if (mCallingUid != Binder.getCallingUid()) {
19749                 throw new SecurityException("Caller " + mCallingUid
19750                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19751             }
19752         }
19753
19754         @Override
19755         public void finishAndRemoveTask() {
19756             checkCaller();
19757
19758             synchronized (ActivityManagerService.this) {
19759                 long origId = Binder.clearCallingIdentity();
19760                 try {
19761                     if (!removeTaskByIdLocked(mTaskId, false)) {
19762                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19763                     }
19764                 } finally {
19765                     Binder.restoreCallingIdentity(origId);
19766                 }
19767             }
19768         }
19769
19770         @Override
19771         public ActivityManager.RecentTaskInfo getTaskInfo() {
19772             checkCaller();
19773
19774             synchronized (ActivityManagerService.this) {
19775                 long origId = Binder.clearCallingIdentity();
19776                 try {
19777                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19778                     if (tr == null) {
19779                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19780                     }
19781                     return createRecentTaskInfoFromTaskRecord(tr);
19782                 } finally {
19783                     Binder.restoreCallingIdentity(origId);
19784                 }
19785             }
19786         }
19787
19788         @Override
19789         public void moveToFront() {
19790             checkCaller();
19791             // Will bring task to front if it already has a root activity.
19792             startActivityFromRecentsInner(mTaskId, null);
19793         }
19794
19795         @Override
19796         public int startActivity(IBinder whoThread, String callingPackage,
19797                 Intent intent, String resolvedType, Bundle options) {
19798             checkCaller();
19799
19800             int callingUser = UserHandle.getCallingUserId();
19801             TaskRecord tr;
19802             IApplicationThread appThread;
19803             synchronized (ActivityManagerService.this) {
19804                 tr = recentTaskForIdLocked(mTaskId);
19805                 if (tr == null) {
19806                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19807                 }
19808                 appThread = ApplicationThreadNative.asInterface(whoThread);
19809                 if (appThread == null) {
19810                     throw new IllegalArgumentException("Bad app thread " + appThread);
19811                 }
19812             }
19813             return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19814                     resolvedType, null, null, null, null, 0, 0, null, null,
19815                     null, options, callingUser, null, tr);
19816         }
19817
19818         @Override
19819         public void setExcludeFromRecents(boolean exclude) {
19820             checkCaller();
19821
19822             synchronized (ActivityManagerService.this) {
19823                 long origId = Binder.clearCallingIdentity();
19824                 try {
19825                     TaskRecord tr = recentTaskForIdLocked(mTaskId);
19826                     if (tr == null) {
19827                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19828                     }
19829                     Intent intent = tr.getBaseIntent();
19830                     if (exclude) {
19831                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19832                     } else {
19833                         intent.setFlags(intent.getFlags()
19834                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19835                     }
19836                 } finally {
19837                     Binder.restoreCallingIdentity(origId);
19838                 }
19839             }
19840         }
19841     }
19842 }