ActivityManagerService.java revision b3af4ec6bae4fe93d40f021e54cbbce10cc7b4c6
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
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.os.storage.IMountService;
52import android.os.storage.StorageManager;
53import android.service.voice.IVoiceInteractionSession;
54import android.util.ArrayMap;
55import android.util.ArraySet;
56import android.util.SparseIntArray;
57
58import com.android.internal.R;
59import com.android.internal.annotations.GuardedBy;
60import com.android.internal.app.IAppOpsService;
61import com.android.internal.app.IVoiceInteractor;
62import com.android.internal.app.ProcessMap;
63import com.android.internal.app.ProcessStats;
64import com.android.internal.content.PackageMonitor;
65import com.android.internal.os.BackgroundThread;
66import com.android.internal.os.BatteryStatsImpl;
67import com.android.internal.os.ProcessCpuTracker;
68import com.android.internal.os.TransferPipe;
69import com.android.internal.os.Zygote;
70import com.android.internal.util.FastPrintWriter;
71import com.android.internal.util.FastXmlSerializer;
72import com.android.internal.util.MemInfoReader;
73import com.android.internal.util.Preconditions;
74import com.android.server.AppOpsService;
75import com.android.server.AttributeCache;
76import com.android.server.IntentResolver;
77import com.android.server.LocalServices;
78import com.android.server.ServiceThread;
79import com.android.server.SystemService;
80import com.android.server.SystemServiceManager;
81import com.android.server.Watchdog;
82import com.android.server.am.ActivityStack.ActivityState;
83import com.android.server.firewall.IntentFirewall;
84import com.android.server.pm.UserManagerService;
85import com.android.server.wm.AppTransition;
86import com.android.server.wm.WindowManagerService;
87import com.google.android.collect.Lists;
88import com.google.android.collect.Maps;
89
90import libcore.io.IoUtils;
91
92import org.xmlpull.v1.XmlPullParser;
93import org.xmlpull.v1.XmlPullParserException;
94import org.xmlpull.v1.XmlSerializer;
95
96import android.app.Activity;
97import android.app.ActivityManager;
98import android.app.ActivityManager.RunningTaskInfo;
99import android.app.ActivityManager.StackInfo;
100import android.app.ActivityManagerInternal;
101import android.app.ActivityManagerNative;
102import android.app.ActivityOptions;
103import android.app.ActivityThread;
104import android.app.AlertDialog;
105import android.app.AppGlobals;
106import android.app.ApplicationErrorReport;
107import android.app.Dialog;
108import android.app.IActivityController;
109import android.app.IApplicationThread;
110import android.app.IInstrumentationWatcher;
111import android.app.INotificationManager;
112import android.app.IProcessObserver;
113import android.app.IServiceConnection;
114import android.app.IStopUserCallback;
115import android.app.IUiAutomationConnection;
116import android.app.IUserSwitchObserver;
117import android.app.Instrumentation;
118import android.app.Notification;
119import android.app.NotificationManager;
120import android.app.PendingIntent;
121import android.app.backup.IBackupManager;
122import android.content.ActivityNotFoundException;
123import android.content.BroadcastReceiver;
124import android.content.ClipData;
125import android.content.ComponentCallbacks2;
126import android.content.ComponentName;
127import android.content.ContentProvider;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.DialogInterface;
131import android.content.IContentProvider;
132import android.content.IIntentReceiver;
133import android.content.IIntentSender;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.pm.ActivityInfo;
138import android.content.pm.ApplicationInfo;
139import android.content.pm.ConfigurationInfo;
140import android.content.pm.IPackageDataObserver;
141import android.content.pm.IPackageManager;
142import android.content.pm.InstrumentationInfo;
143import android.content.pm.PackageInfo;
144import android.content.pm.PackageManager;
145import android.content.pm.ParceledListSlice;
146import android.content.pm.UserInfo;
147import android.content.pm.PackageManager.NameNotFoundException;
148import android.content.pm.PathPermission;
149import android.content.pm.ProviderInfo;
150import android.content.pm.ResolveInfo;
151import android.content.pm.ServiceInfo;
152import android.content.res.CompatibilityInfo;
153import android.content.res.Configuration;
154import android.net.Proxy;
155import android.net.ProxyInfo;
156import android.net.Uri;
157import android.os.Binder;
158import android.os.Build;
159import android.os.Bundle;
160import android.os.Debug;
161import android.os.DropBoxManager;
162import android.os.Environment;
163import android.os.FactoryTest;
164import android.os.FileObserver;
165import android.os.FileUtils;
166import android.os.Handler;
167import android.os.IBinder;
168import android.os.IPermissionController;
169import android.os.IRemoteCallback;
170import android.os.IUserManager;
171import android.os.Looper;
172import android.os.Message;
173import android.os.Parcel;
174import android.os.ParcelFileDescriptor;
175import android.os.Process;
176import android.os.RemoteCallbackList;
177import android.os.RemoteException;
178import android.os.SELinux;
179import android.os.ServiceManager;
180import android.os.StrictMode;
181import android.os.SystemClock;
182import android.os.SystemProperties;
183import android.os.UpdateLock;
184import android.os.UserHandle;
185import android.os.UserManager;
186import android.provider.Settings;
187import android.text.format.DateUtils;
188import android.text.format.Time;
189import android.util.AtomicFile;
190import android.util.EventLog;
191import android.util.Log;
192import android.util.Pair;
193import android.util.PrintWriterPrinter;
194import android.util.Slog;
195import android.util.SparseArray;
196import android.util.TimeUtils;
197import android.util.Xml;
198import android.view.Gravity;
199import android.view.LayoutInflater;
200import android.view.View;
201import android.view.WindowManager;
202import dalvik.system.VMRuntime;
203
204import java.io.BufferedInputStream;
205import java.io.BufferedOutputStream;
206import java.io.DataInputStream;
207import java.io.DataOutputStream;
208import java.io.File;
209import java.io.FileDescriptor;
210import java.io.FileInputStream;
211import java.io.FileNotFoundException;
212import java.io.FileOutputStream;
213import java.io.IOException;
214import java.io.InputStreamReader;
215import java.io.PrintWriter;
216import java.io.StringWriter;
217import java.lang.ref.WeakReference;
218import java.util.ArrayList;
219import java.util.Arrays;
220import java.util.Collections;
221import java.util.Comparator;
222import java.util.HashMap;
223import java.util.HashSet;
224import java.util.Iterator;
225import java.util.List;
226import java.util.Locale;
227import java.util.Map;
228import java.util.Set;
229import java.util.concurrent.atomic.AtomicBoolean;
230import java.util.concurrent.atomic.AtomicLong;
231
232public final class ActivityManagerService extends ActivityManagerNative
233        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
234
235    private static final String USER_DATA_DIR = "/data/user/";
236    // File that stores last updated system version and called preboot receivers
237    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
238
239    static final String TAG = "ActivityManager";
240    static final String TAG_MU = "ActivityManagerServiceMU";
241    static final boolean DEBUG = false;
242    static final boolean localLOGV = DEBUG;
243    static final boolean DEBUG_BACKUP = localLOGV || false;
244    static final boolean DEBUG_BROADCAST = localLOGV || false;
245    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
246    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
247    static final boolean DEBUG_CLEANUP = localLOGV || false;
248    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
249    static final boolean DEBUG_FOCUS = false;
250    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
251    static final boolean DEBUG_MU = localLOGV || false;
252    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
253    static final boolean DEBUG_LRU = localLOGV || false;
254    static final boolean DEBUG_PAUSE = localLOGV || false;
255    static final boolean DEBUG_POWER = localLOGV || false;
256    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
257    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
258    static final boolean DEBUG_PROCESSES = localLOGV || false;
259    static final boolean DEBUG_PROVIDER = localLOGV || false;
260    static final boolean DEBUG_RESULTS = localLOGV || false;
261    static final boolean DEBUG_SERVICE = localLOGV || false;
262    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
263    static final boolean DEBUG_STACK = localLOGV || false;
264    static final boolean DEBUG_SWITCH = localLOGV || false;
265    static final boolean DEBUG_TASKS = localLOGV || false;
266    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
267    static final boolean DEBUG_TRANSITION = localLOGV || false;
268    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
269    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
270    static final boolean DEBUG_VISBILITY = localLOGV || false;
271    static final boolean DEBUG_PSS = localLOGV || false;
272    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
273    static final boolean DEBUG_RECENTS = localLOGV || false;
274    static final boolean VALIDATE_TOKENS = false;
275    static final boolean SHOW_ACTIVITY_START_TIME = true;
276
277    // Control over CPU and battery monitoring.
278    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
279    static final boolean MONITOR_CPU_USAGE = true;
280    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
281    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
282    static final boolean MONITOR_THREAD_CPU_USAGE = false;
283
284    // The flags that are set for all calls we make to the package manager.
285    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
286
287    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
288
289    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
290
291    // Maximum number recent bitmaps to keep in memory.
292    static final int MAX_RECENT_BITMAPS = 5;
293
294    // Amount of time after a call to stopAppSwitches() during which we will
295    // prevent further untrusted switches from happening.
296    static final long APP_SWITCH_DELAY_TIME = 5*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real.
300    static final int PROC_START_TIMEOUT = 10*1000;
301
302    // How long we wait for a launched process to attach to the activity manager
303    // before we decide it's never going to come up for real, when the process was
304    // started with a wrapper for instrumentation (such as Valgrind) because it
305    // could take much longer than usual.
306    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
307
308    // How long to wait after going idle before forcing apps to GC.
309    static final int GC_TIMEOUT = 5*1000;
310
311    // The minimum amount of time between successive GC requests for a process.
312    static final int GC_MIN_INTERVAL = 60*1000;
313
314    // The minimum amount of time between successive PSS requests for a process.
315    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
316
317    // The minimum amount of time between successive PSS requests for a process
318    // when the request is due to the memory state being lowered.
319    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
320
321    // The rate at which we check for apps using excessive power -- 15 mins.
322    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on wake locks to start killing things.
326    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // The minimum sample duration we will allow before deciding we have
329    // enough data on CPU usage to start killing things.
330    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
331
332    // How long we allow a receiver to run before giving up on it.
333    static final int BROADCAST_FG_TIMEOUT = 10*1000;
334    static final int BROADCAST_BG_TIMEOUT = 60*1000;
335
336    // How long we wait until we timeout on key dispatching.
337    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
338
339    // How long we wait until we timeout on key dispatching during instrumentation.
340    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
341
342    // Amount of time we wait for observers to handle a user switch before
343    // giving up on them and unfreezing the screen.
344    static final int USER_SWITCH_TIMEOUT = 2*1000;
345
346    // Maximum number of users we allow to be running at a time.
347    static final int MAX_RUNNING_USERS = 3;
348
349    // How long to wait in getAssistContextExtras for the activity and foreground services
350    // to respond with the result.
351    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
352
353    // Maximum number of persisted Uri grants a package is allowed
354    static final int MAX_PERSISTED_URI_GRANTS = 128;
355
356    static final int MY_PID = Process.myPid();
357
358    static final String[] EMPTY_STRING_ARRAY = new String[0];
359
360    // How many bytes to write into the dropbox log before truncating
361    static final int DROPBOX_MAX_SIZE = 256 * 1024;
362
363    // Access modes for handleIncomingUser.
364    static final int ALLOW_NON_FULL = 0;
365    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
366    static final int ALLOW_FULL_ONLY = 2;
367
368    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
369
370    /** All system services */
371    SystemServiceManager mSystemServiceManager;
372
373    /** Run all ActivityStacks through this */
374    ActivityStackSupervisor mStackSupervisor;
375
376    public IntentFirewall mIntentFirewall;
377
378    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
379    // default actuion automatically.  Important for devices without direct input
380    // devices.
381    private boolean mShowDialogs = true;
382
383    BroadcastQueue mFgBroadcastQueue;
384    BroadcastQueue mBgBroadcastQueue;
385    // Convenient for easy iteration over the queues. Foreground is first
386    // so that dispatch of foreground broadcasts gets precedence.
387    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
388
389    BroadcastQueue broadcastQueueForIntent(Intent intent) {
390        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
391        if (DEBUG_BACKGROUND_BROADCAST) {
392            Slog.i(TAG, "Broadcast intent " + intent + " on "
393                    + (isFg ? "foreground" : "background")
394                    + " queue");
395        }
396        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
397    }
398
399    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
400        for (BroadcastQueue queue : mBroadcastQueues) {
401            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
402            if (r != null) {
403                return r;
404            }
405        }
406        return null;
407    }
408
409    /**
410     * Activity we have told the window manager to have key focus.
411     */
412    ActivityRecord mFocusedActivity = null;
413
414    /**
415     * List of intents that were used to start the most recent tasks.
416     */
417    ArrayList<TaskRecord> mRecentTasks;
418    ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
419
420    /**
421     * For addAppTask: cached of the last activity component that was added.
422     */
423    ComponentName mLastAddedTaskComponent;
424
425    /**
426     * For addAppTask: cached of the last activity uid that was added.
427     */
428    int mLastAddedTaskUid;
429
430    /**
431     * For addAppTask: cached of the last ActivityInfo that was added.
432     */
433    ActivityInfo mLastAddedTaskActivity;
434
435    public class PendingAssistExtras extends Binder implements Runnable {
436        public final ActivityRecord activity;
437        public final Bundle extras;
438        public final Intent intent;
439        public final String hint;
440        public final int userHandle;
441        public boolean haveResult = false;
442        public Bundle result = null;
443        public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
444                String _hint, int _userHandle) {
445            activity = _activity;
446            extras = _extras;
447            intent = _intent;
448            hint = _hint;
449            userHandle = _userHandle;
450        }
451        @Override
452        public void run() {
453            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
454            synchronized (this) {
455                haveResult = true;
456                notifyAll();
457            }
458        }
459    }
460
461    final ArrayList<PendingAssistExtras> mPendingAssistExtras
462            = new ArrayList<PendingAssistExtras>();
463
464    /**
465     * Process management.
466     */
467    final ProcessList mProcessList = new ProcessList();
468
469    /**
470     * All of the applications we currently have running organized by name.
471     * The keys are strings of the application package name (as
472     * returned by the package manager), and the keys are ApplicationRecord
473     * objects.
474     */
475    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
476
477    /**
478     * Tracking long-term execution of processes to look for abuse and other
479     * bad app behavior.
480     */
481    final ProcessStatsService mProcessStats;
482
483    /**
484     * The currently running isolated processes.
485     */
486    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
487
488    /**
489     * Counter for assigning isolated process uids, to avoid frequently reusing the
490     * same ones.
491     */
492    int mNextIsolatedProcessUid = 0;
493
494    /**
495     * The currently running heavy-weight process, if any.
496     */
497    ProcessRecord mHeavyWeightProcess = null;
498
499    /**
500     * The last time that various processes have crashed.
501     */
502    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
503
504    /**
505     * Information about a process that is currently marked as bad.
506     */
507    static final class BadProcessInfo {
508        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
509            this.time = time;
510            this.shortMsg = shortMsg;
511            this.longMsg = longMsg;
512            this.stack = stack;
513        }
514
515        final long time;
516        final String shortMsg;
517        final String longMsg;
518        final String stack;
519    }
520
521    /**
522     * Set of applications that we consider to be bad, and will reject
523     * incoming broadcasts from (which the user has no control over).
524     * Processes are added to this set when they have crashed twice within
525     * a minimum amount of time; they are removed from it when they are
526     * later restarted (hopefully due to some user action).  The value is the
527     * time it was added to the list.
528     */
529    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
530
531    /**
532     * All of the processes we currently have running organized by pid.
533     * The keys are the pid running the application.
534     *
535     * <p>NOTE: This object is protected by its own lock, NOT the global
536     * activity manager lock!
537     */
538    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
539
540    /**
541     * All of the processes that have been forced to be foreground.  The key
542     * is the pid of the caller who requested it (we hold a death
543     * link on it).
544     */
545    abstract class ForegroundToken implements IBinder.DeathRecipient {
546        int pid;
547        IBinder token;
548    }
549    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
550
551    /**
552     * List of records for processes that someone had tried to start before the
553     * system was ready.  We don't start them at that point, but ensure they
554     * are started by the time booting is complete.
555     */
556    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
557
558    /**
559     * List of persistent applications that are in the process
560     * of being started.
561     */
562    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
563
564    /**
565     * Processes that are being forcibly torn down.
566     */
567    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
568
569    /**
570     * List of running applications, sorted by recent usage.
571     * The first entry in the list is the least recently used.
572     */
573    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
574
575    /**
576     * Where in mLruProcesses that the processes hosting activities start.
577     */
578    int mLruProcessActivityStart = 0;
579
580    /**
581     * Where in mLruProcesses that the processes hosting services start.
582     * This is after (lower index) than mLruProcessesActivityStart.
583     */
584    int mLruProcessServiceStart = 0;
585
586    /**
587     * List of processes that should gc as soon as things are idle.
588     */
589    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
590
591    /**
592     * Processes we want to collect PSS data from.
593     */
594    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
595
596    /**
597     * Last time we requested PSS data of all processes.
598     */
599    long mLastFullPssTime = SystemClock.uptimeMillis();
600
601    /**
602     * If set, the next time we collect PSS data we should do a full collection
603     * with data from native processes and the kernel.
604     */
605    boolean mFullPssPending = false;
606
607    /**
608     * This is the process holding what we currently consider to be
609     * the "home" activity.
610     */
611    ProcessRecord mHomeProcess;
612
613    /**
614     * This is the process holding the activity the user last visited that
615     * is in a different process from the one they are currently in.
616     */
617    ProcessRecord mPreviousProcess;
618
619    /**
620     * The time at which the previous process was last visible.
621     */
622    long mPreviousProcessVisibleTime;
623
624    /**
625     * Which uses have been started, so are allowed to run code.
626     */
627    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
628
629    /**
630     * LRU list of history of current users.  Most recently current is at the end.
631     */
632    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
633
634    /**
635     * Constant array of the users that are currently started.
636     */
637    int[] mStartedUserArray = new int[] { 0 };
638
639    /**
640     * Registered observers of the user switching mechanics.
641     */
642    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
643            = new RemoteCallbackList<IUserSwitchObserver>();
644
645    /**
646     * Currently active user switch.
647     */
648    Object mCurUserSwitchCallback;
649
650    /**
651     * Packages that the user has asked to have run in screen size
652     * compatibility mode instead of filling the screen.
653     */
654    final CompatModePackages mCompatModePackages;
655
656    /**
657     * Set of IntentSenderRecord objects that are currently active.
658     */
659    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
660            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
661
662    /**
663     * Fingerprints (hashCode()) of stack traces that we've
664     * already logged DropBox entries for.  Guarded by itself.  If
665     * something (rogue user app) forces this over
666     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
667     */
668    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
669    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
670
671    /**
672     * Strict Mode background batched logging state.
673     *
674     * The string buffer is guarded by itself, and its lock is also
675     * used to determine if another batched write is already
676     * in-flight.
677     */
678    private final StringBuilder mStrictModeBuffer = new StringBuilder();
679
680    /**
681     * Keeps track of all IIntentReceivers that have been registered for
682     * broadcasts.  Hash keys are the receiver IBinder, hash value is
683     * a ReceiverList.
684     */
685    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
686            new HashMap<IBinder, ReceiverList>();
687
688    /**
689     * Resolver for broadcast intents to registered receivers.
690     * Holds BroadcastFilter (subclass of IntentFilter).
691     */
692    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
693            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
694        @Override
695        protected boolean allowFilterResult(
696                BroadcastFilter filter, List<BroadcastFilter> dest) {
697            IBinder target = filter.receiverList.receiver.asBinder();
698            for (int i=dest.size()-1; i>=0; i--) {
699                if (dest.get(i).receiverList.receiver.asBinder() == target) {
700                    return false;
701                }
702            }
703            return true;
704        }
705
706        @Override
707        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
708            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
709                    || userId == filter.owningUserId) {
710                return super.newResult(filter, match, userId);
711            }
712            return null;
713        }
714
715        @Override
716        protected BroadcastFilter[] newArray(int size) {
717            return new BroadcastFilter[size];
718        }
719
720        @Override
721        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
722            return packageName.equals(filter.packageName);
723        }
724    };
725
726    /**
727     * State of all active sticky broadcasts per user.  Keys are the action of the
728     * sticky Intent, values are an ArrayList of all broadcasted intents with
729     * that action (which should usually be one).  The SparseArray is keyed
730     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
731     * for stickies that are sent to all users.
732     */
733    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
734            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
735
736    final ActiveServices mServices;
737
738    /**
739     * Backup/restore process management
740     */
741    String mBackupAppName = null;
742    BackupRecord mBackupTarget = null;
743
744    final ProviderMap mProviderMap;
745
746    /**
747     * List of content providers who have clients waiting for them.  The
748     * application is currently being launched and the provider will be
749     * removed from this list once it is published.
750     */
751    final ArrayList<ContentProviderRecord> mLaunchingProviders
752            = new ArrayList<ContentProviderRecord>();
753
754    /**
755     * File storing persisted {@link #mGrantedUriPermissions}.
756     */
757    private final AtomicFile mGrantFile;
758
759    /** XML constants used in {@link #mGrantFile} */
760    private static final String TAG_URI_GRANTS = "uri-grants";
761    private static final String TAG_URI_GRANT = "uri-grant";
762    private static final String ATTR_USER_HANDLE = "userHandle";
763    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
764    private static final String ATTR_TARGET_USER_ID = "targetUserId";
765    private static final String ATTR_SOURCE_PKG = "sourcePkg";
766    private static final String ATTR_TARGET_PKG = "targetPkg";
767    private static final String ATTR_URI = "uri";
768    private static final String ATTR_MODE_FLAGS = "modeFlags";
769    private static final String ATTR_CREATED_TIME = "createdTime";
770    private static final String ATTR_PREFIX = "prefix";
771
772    /**
773     * Global set of specific {@link Uri} permissions that have been granted.
774     * This optimized lookup structure maps from {@link UriPermission#targetUid}
775     * to {@link UriPermission#uri} to {@link UriPermission}.
776     */
777    @GuardedBy("this")
778    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
779            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
780
781    public static class GrantUri {
782        public final int sourceUserId;
783        public final Uri uri;
784        public boolean prefix;
785
786        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
787            this.sourceUserId = sourceUserId;
788            this.uri = uri;
789            this.prefix = prefix;
790        }
791
792        @Override
793        public int hashCode() {
794            return toString().hashCode();
795        }
796
797        @Override
798        public boolean equals(Object o) {
799            if (o instanceof GrantUri) {
800                GrantUri other = (GrantUri) o;
801                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
802                        && prefix == other.prefix;
803            }
804            return false;
805        }
806
807        @Override
808        public String toString() {
809            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
810            if (prefix) result += " [prefix]";
811            return result;
812        }
813
814        public String toSafeString() {
815            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
816            if (prefix) result += " [prefix]";
817            return result;
818        }
819
820        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
821            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
822                    ContentProvider.getUriWithoutUserId(uri), false);
823        }
824    }
825
826    CoreSettingsObserver mCoreSettingsObserver;
827
828    /**
829     * Thread-local storage used to carry caller permissions over through
830     * indirect content-provider access.
831     */
832    private class Identity {
833        public int pid;
834        public int uid;
835
836        Identity(int _pid, int _uid) {
837            pid = _pid;
838            uid = _uid;
839        }
840    }
841
842    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
843
844    /**
845     * All information we have collected about the runtime performance of
846     * any user id that can impact battery performance.
847     */
848    final BatteryStatsService mBatteryStatsService;
849
850    /**
851     * Information about component usage
852     */
853    UsageStatsManagerInternal mUsageStatsService;
854
855    /**
856     * Information about and control over application operations
857     */
858    final AppOpsService mAppOpsService;
859
860    /**
861     * Save recent tasks information across reboots.
862     */
863    final TaskPersister mTaskPersister;
864
865    /**
866     * Current configuration information.  HistoryRecord objects are given
867     * a reference to this object to indicate which configuration they are
868     * currently running in, so this object must be kept immutable.
869     */
870    Configuration mConfiguration = new Configuration();
871
872    /**
873     * Current sequencing integer of the configuration, for skipping old
874     * configurations.
875     */
876    int mConfigurationSeq = 0;
877
878    /**
879     * Hardware-reported OpenGLES version.
880     */
881    final int GL_ES_VERSION;
882
883    /**
884     * List of initialization arguments to pass to all processes when binding applications to them.
885     * For example, references to the commonly used services.
886     */
887    HashMap<String, IBinder> mAppBindArgs;
888
889    /**
890     * Temporary to avoid allocations.  Protected by main lock.
891     */
892    final StringBuilder mStringBuilder = new StringBuilder(256);
893
894    /**
895     * Used to control how we initialize the service.
896     */
897    ComponentName mTopComponent;
898    String mTopAction = Intent.ACTION_MAIN;
899    String mTopData;
900    boolean mProcessesReady = false;
901    boolean mSystemReady = false;
902    boolean mBooting = false;
903    boolean mCallFinishBooting = false;
904    boolean mBootAnimationComplete = false;
905    boolean mWaitingUpdate = false;
906    boolean mDidUpdate = false;
907    boolean mOnBattery = false;
908    boolean mLaunchWarningShown = false;
909
910    Context mContext;
911
912    int mFactoryTest;
913
914    boolean mCheckedForSetup;
915
916    /**
917     * The time at which we will allow normal application switches again,
918     * after a call to {@link #stopAppSwitches()}.
919     */
920    long mAppSwitchesAllowedTime;
921
922    /**
923     * This is set to true after the first switch after mAppSwitchesAllowedTime
924     * is set; any switches after that will clear the time.
925     */
926    boolean mDidAppSwitch;
927
928    /**
929     * Last time (in realtime) at which we checked for power usage.
930     */
931    long mLastPowerCheckRealtime;
932
933    /**
934     * Last time (in uptime) at which we checked for power usage.
935     */
936    long mLastPowerCheckUptime;
937
938    /**
939     * Set while we are wanting to sleep, to prevent any
940     * activities from being started/resumed.
941     */
942    private boolean mSleeping = false;
943
944    /**
945     * Set while we are running a voice interaction.  This overrides
946     * sleeping while it is active.
947     */
948    private boolean mRunningVoice = false;
949
950    /**
951     * State of external calls telling us if the device is asleep.
952     */
953    private boolean mWentToSleep = false;
954
955    /**
956     * State of external call telling us if the lock screen is shown.
957     */
958    private boolean mLockScreenShown = false;
959
960    /**
961     * Set if we are shutting down the system, similar to sleeping.
962     */
963    boolean mShuttingDown = false;
964
965    /**
966     * Current sequence id for oom_adj computation traversal.
967     */
968    int mAdjSeq = 0;
969
970    /**
971     * Current sequence id for process LRU updating.
972     */
973    int mLruSeq = 0;
974
975    /**
976     * Keep track of the non-cached/empty process we last found, to help
977     * determine how to distribute cached/empty processes next time.
978     */
979    int mNumNonCachedProcs = 0;
980
981    /**
982     * Keep track of the number of cached hidden procs, to balance oom adj
983     * distribution between those and empty procs.
984     */
985    int mNumCachedHiddenProcs = 0;
986
987    /**
988     * Keep track of the number of service processes we last found, to
989     * determine on the next iteration which should be B services.
990     */
991    int mNumServiceProcs = 0;
992    int mNewNumAServiceProcs = 0;
993    int mNewNumServiceProcs = 0;
994
995    /**
996     * Allow the current computed overall memory level of the system to go down?
997     * This is set to false when we are killing processes for reasons other than
998     * memory management, so that the now smaller process list will not be taken as
999     * an indication that memory is tighter.
1000     */
1001    boolean mAllowLowerMemLevel = false;
1002
1003    /**
1004     * The last computed memory level, for holding when we are in a state that
1005     * processes are going away for other reasons.
1006     */
1007    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1008
1009    /**
1010     * The last total number of process we have, to determine if changes actually look
1011     * like a shrinking number of process due to lower RAM.
1012     */
1013    int mLastNumProcesses;
1014
1015    /**
1016     * The uptime of the last time we performed idle maintenance.
1017     */
1018    long mLastIdleTime = SystemClock.uptimeMillis();
1019
1020    /**
1021     * Total time spent with RAM that has been added in the past since the last idle time.
1022     */
1023    long mLowRamTimeSinceLastIdle = 0;
1024
1025    /**
1026     * If RAM is currently low, when that horrible situation started.
1027     */
1028    long mLowRamStartTime = 0;
1029
1030    /**
1031     * For reporting to battery stats the current top application.
1032     */
1033    private String mCurResumedPackage = null;
1034    private int mCurResumedUid = -1;
1035
1036    /**
1037     * For reporting to battery stats the apps currently running foreground
1038     * service.  The ProcessMap is package/uid tuples; each of these contain
1039     * an array of the currently foreground processes.
1040     */
1041    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1042            = new ProcessMap<ArrayList<ProcessRecord>>();
1043
1044    /**
1045     * This is set if we had to do a delayed dexopt of an app before launching
1046     * it, to increase the ANR timeouts in that case.
1047     */
1048    boolean mDidDexOpt;
1049
1050    /**
1051     * Set if the systemServer made a call to enterSafeMode.
1052     */
1053    boolean mSafeMode;
1054
1055    String mDebugApp = null;
1056    boolean mWaitForDebugger = false;
1057    boolean mDebugTransient = false;
1058    String mOrigDebugApp = null;
1059    boolean mOrigWaitForDebugger = false;
1060    boolean mAlwaysFinishActivities = false;
1061    IActivityController mController = null;
1062    String mProfileApp = null;
1063    ProcessRecord mProfileProc = null;
1064    String mProfileFile;
1065    ParcelFileDescriptor mProfileFd;
1066    int mSamplingInterval = 0;
1067    boolean mAutoStopProfiler = false;
1068    int mProfileType = 0;
1069    String mOpenGlTraceApp = null;
1070
1071    static class ProcessChangeItem {
1072        static final int CHANGE_ACTIVITIES = 1<<0;
1073        static final int CHANGE_PROCESS_STATE = 1<<1;
1074        int changes;
1075        int uid;
1076        int pid;
1077        int processState;
1078        boolean foregroundActivities;
1079    }
1080
1081    final RemoteCallbackList<IProcessObserver> mProcessObservers
1082            = new RemoteCallbackList<IProcessObserver>();
1083    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1084
1085    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1086            = new ArrayList<ProcessChangeItem>();
1087    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1088            = new ArrayList<ProcessChangeItem>();
1089
1090    /**
1091     * Runtime CPU use collection thread.  This object's lock is used to
1092     * perform synchronization with the thread (notifying it to run).
1093     */
1094    final Thread mProcessCpuThread;
1095
1096    /**
1097     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1098     * Must acquire this object's lock when accessing it.
1099     * NOTE: this lock will be held while doing long operations (trawling
1100     * through all processes in /proc), so it should never be acquired by
1101     * any critical paths such as when holding the main activity manager lock.
1102     */
1103    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1104            MONITOR_THREAD_CPU_USAGE);
1105    final AtomicLong mLastCpuTime = new AtomicLong(0);
1106    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1107
1108    long mLastWriteTime = 0;
1109
1110    /**
1111     * Used to retain an update lock when the foreground activity is in
1112     * immersive mode.
1113     */
1114    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1115
1116    /**
1117     * Set to true after the system has finished booting.
1118     */
1119    boolean mBooted = false;
1120
1121    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1122    int mProcessLimitOverride = -1;
1123
1124    WindowManagerService mWindowManager;
1125
1126    final ActivityThread mSystemThread;
1127
1128    // Holds the current foreground user's id
1129    int mCurrentUserId = 0;
1130    // Holds the target user's id during a user switch
1131    int mTargetUserId = UserHandle.USER_NULL;
1132    // If there are multiple profiles for the current user, their ids are here
1133    // Currently only the primary user can have managed profiles
1134    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1135
1136    /**
1137     * Mapping from each known user ID to the profile group ID it is associated with.
1138     */
1139    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1140
1141    private UserManagerService mUserManager;
1142
1143    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1144        final ProcessRecord mApp;
1145        final int mPid;
1146        final IApplicationThread mAppThread;
1147
1148        AppDeathRecipient(ProcessRecord app, int pid,
1149                IApplicationThread thread) {
1150            if (localLOGV) Slog.v(
1151                TAG, "New death recipient " + this
1152                + " for thread " + thread.asBinder());
1153            mApp = app;
1154            mPid = pid;
1155            mAppThread = thread;
1156        }
1157
1158        @Override
1159        public void binderDied() {
1160            if (localLOGV) Slog.v(
1161                TAG, "Death received in " + this
1162                + " for thread " + mAppThread.asBinder());
1163            synchronized(ActivityManagerService.this) {
1164                appDiedLocked(mApp, mPid, mAppThread);
1165            }
1166        }
1167    }
1168
1169    static final int SHOW_ERROR_MSG = 1;
1170    static final int SHOW_NOT_RESPONDING_MSG = 2;
1171    static final int SHOW_FACTORY_ERROR_MSG = 3;
1172    static final int UPDATE_CONFIGURATION_MSG = 4;
1173    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1174    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1175    static final int SERVICE_TIMEOUT_MSG = 12;
1176    static final int UPDATE_TIME_ZONE = 13;
1177    static final int SHOW_UID_ERROR_MSG = 14;
1178    static final int IM_FEELING_LUCKY_MSG = 15;
1179    static final int PROC_START_TIMEOUT_MSG = 20;
1180    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1181    static final int KILL_APPLICATION_MSG = 22;
1182    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1183    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1184    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1185    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1186    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1187    static final int CLEAR_DNS_CACHE_MSG = 28;
1188    static final int UPDATE_HTTP_PROXY_MSG = 29;
1189    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1190    static final int DISPATCH_PROCESSES_CHANGED = 31;
1191    static final int DISPATCH_PROCESS_DIED = 32;
1192    static final int REPORT_MEM_USAGE_MSG = 33;
1193    static final int REPORT_USER_SWITCH_MSG = 34;
1194    static final int CONTINUE_USER_SWITCH_MSG = 35;
1195    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1196    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1197    static final int PERSIST_URI_GRANTS_MSG = 38;
1198    static final int REQUEST_ALL_PSS_MSG = 39;
1199    static final int START_PROFILES_MSG = 40;
1200    static final int UPDATE_TIME = 41;
1201    static final int SYSTEM_USER_START_MSG = 42;
1202    static final int SYSTEM_USER_CURRENT_MSG = 43;
1203    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1204    static final int FINISH_BOOTING_MSG = 45;
1205    static final int START_USER_SWITCH_MSG = 46;
1206    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1207
1208    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1209    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1210    static final int FIRST_COMPAT_MODE_MSG = 300;
1211    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1212
1213    AlertDialog mUidAlert;
1214    CompatModeDialog mCompatModeDialog;
1215    long mLastMemUsageReportTime = 0;
1216
1217    private LockToAppRequestDialog mLockToAppRequest;
1218
1219    /**
1220     * Flag whether the current user is a "monkey", i.e. whether
1221     * the UI is driven by a UI automation tool.
1222     */
1223    private boolean mUserIsMonkey;
1224
1225    /** Flag whether the device has a Recents UI */
1226    boolean mHasRecents;
1227
1228    /** The dimensions of the thumbnails in the Recents UI. */
1229    int mThumbnailWidth;
1230    int mThumbnailHeight;
1231
1232    final ServiceThread mHandlerThread;
1233    final MainHandler mHandler;
1234
1235    final class MainHandler extends Handler {
1236        public MainHandler(Looper looper) {
1237            super(looper, null, true);
1238        }
1239
1240        @Override
1241        public void handleMessage(Message msg) {
1242            switch (msg.what) {
1243            case SHOW_ERROR_MSG: {
1244                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1245                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1246                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1247                synchronized (ActivityManagerService.this) {
1248                    ProcessRecord proc = (ProcessRecord)data.get("app");
1249                    AppErrorResult res = (AppErrorResult) data.get("result");
1250                    if (proc != null && proc.crashDialog != null) {
1251                        Slog.e(TAG, "App already has crash dialog: " + proc);
1252                        if (res != null) {
1253                            res.set(0);
1254                        }
1255                        return;
1256                    }
1257                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1258                            >= Process.FIRST_APPLICATION_UID
1259                            && proc.pid != MY_PID);
1260                    for (int userId : mCurrentProfileIds) {
1261                        isBackground &= (proc.userId != userId);
1262                    }
1263                    if (isBackground && !showBackground) {
1264                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1265                        if (res != null) {
1266                            res.set(0);
1267                        }
1268                        return;
1269                    }
1270                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1271                        Dialog d = new AppErrorDialog(mContext,
1272                                ActivityManagerService.this, res, proc);
1273                        d.show();
1274                        proc.crashDialog = d;
1275                    } else {
1276                        // The device is asleep, so just pretend that the user
1277                        // saw a crash dialog and hit "force quit".
1278                        if (res != null) {
1279                            res.set(0);
1280                        }
1281                    }
1282                }
1283
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_NOT_RESPONDING_MSG: {
1287                synchronized (ActivityManagerService.this) {
1288                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1289                    ProcessRecord proc = (ProcessRecord)data.get("app");
1290                    if (proc != null && proc.anrDialog != null) {
1291                        Slog.e(TAG, "App already has anr dialog: " + proc);
1292                        return;
1293                    }
1294
1295                    Intent intent = new Intent("android.intent.action.ANR");
1296                    if (!mProcessesReady) {
1297                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1298                                | Intent.FLAG_RECEIVER_FOREGROUND);
1299                    }
1300                    broadcastIntentLocked(null, null, intent,
1301                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1302                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1303
1304                    if (mShowDialogs) {
1305                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1306                                mContext, proc, (ActivityRecord)data.get("activity"),
1307                                msg.arg1 != 0);
1308                        d.show();
1309                        proc.anrDialog = d;
1310                    } else {
1311                        // Just kill the app if there is no dialog to be shown.
1312                        killAppAtUsersRequest(proc, null);
1313                    }
1314                }
1315
1316                ensureBootCompleted();
1317            } break;
1318            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1319                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1320                synchronized (ActivityManagerService.this) {
1321                    ProcessRecord proc = (ProcessRecord) data.get("app");
1322                    if (proc == null) {
1323                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1324                        break;
1325                    }
1326                    if (proc.crashDialog != null) {
1327                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1328                        return;
1329                    }
1330                    AppErrorResult res = (AppErrorResult) data.get("result");
1331                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1332                        Dialog d = new StrictModeViolationDialog(mContext,
1333                                ActivityManagerService.this, res, proc);
1334                        d.show();
1335                        proc.crashDialog = d;
1336                    } else {
1337                        // The device is asleep, so just pretend that the user
1338                        // saw a crash dialog and hit "force quit".
1339                        res.set(0);
1340                    }
1341                }
1342                ensureBootCompleted();
1343            } break;
1344            case SHOW_FACTORY_ERROR_MSG: {
1345                Dialog d = new FactoryErrorDialog(
1346                    mContext, msg.getData().getCharSequence("msg"));
1347                d.show();
1348                ensureBootCompleted();
1349            } break;
1350            case UPDATE_CONFIGURATION_MSG: {
1351                final ContentResolver resolver = mContext.getContentResolver();
1352                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1353            } break;
1354            case GC_BACKGROUND_PROCESSES_MSG: {
1355                synchronized (ActivityManagerService.this) {
1356                    performAppGcsIfAppropriateLocked();
1357                }
1358            } break;
1359            case WAIT_FOR_DEBUGGER_MSG: {
1360                synchronized (ActivityManagerService.this) {
1361                    ProcessRecord app = (ProcessRecord)msg.obj;
1362                    if (msg.arg1 != 0) {
1363                        if (!app.waitedForDebugger) {
1364                            Dialog d = new AppWaitingForDebuggerDialog(
1365                                    ActivityManagerService.this,
1366                                    mContext, app);
1367                            app.waitDialog = d;
1368                            app.waitedForDebugger = true;
1369                            d.show();
1370                        }
1371                    } else {
1372                        if (app.waitDialog != null) {
1373                            app.waitDialog.dismiss();
1374                            app.waitDialog = null;
1375                        }
1376                    }
1377                }
1378            } break;
1379            case SERVICE_TIMEOUT_MSG: {
1380                if (mDidDexOpt) {
1381                    mDidDexOpt = false;
1382                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1383                    nmsg.obj = msg.obj;
1384                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1385                    return;
1386                }
1387                mServices.serviceTimeout((ProcessRecord)msg.obj);
1388            } break;
1389            case UPDATE_TIME_ZONE: {
1390                synchronized (ActivityManagerService.this) {
1391                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1392                        ProcessRecord r = mLruProcesses.get(i);
1393                        if (r.thread != null) {
1394                            try {
1395                                r.thread.updateTimeZone();
1396                            } catch (RemoteException ex) {
1397                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1398                            }
1399                        }
1400                    }
1401                }
1402            } break;
1403            case CLEAR_DNS_CACHE_MSG: {
1404                synchronized (ActivityManagerService.this) {
1405                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1406                        ProcessRecord r = mLruProcesses.get(i);
1407                        if (r.thread != null) {
1408                            try {
1409                                r.thread.clearDnsCache();
1410                            } catch (RemoteException ex) {
1411                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1412                            }
1413                        }
1414                    }
1415                }
1416            } break;
1417            case UPDATE_HTTP_PROXY_MSG: {
1418                ProxyInfo proxy = (ProxyInfo)msg.obj;
1419                String host = "";
1420                String port = "";
1421                String exclList = "";
1422                Uri pacFileUrl = Uri.EMPTY;
1423                if (proxy != null) {
1424                    host = proxy.getHost();
1425                    port = Integer.toString(proxy.getPort());
1426                    exclList = proxy.getExclusionListAsString();
1427                    pacFileUrl = proxy.getPacFileUrl();
1428                }
1429                synchronized (ActivityManagerService.this) {
1430                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1431                        ProcessRecord r = mLruProcesses.get(i);
1432                        if (r.thread != null) {
1433                            try {
1434                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1435                            } catch (RemoteException ex) {
1436                                Slog.w(TAG, "Failed to update http proxy for: " +
1437                                        r.info.processName);
1438                            }
1439                        }
1440                    }
1441                }
1442            } break;
1443            case SHOW_UID_ERROR_MSG: {
1444                String title = "System UIDs Inconsistent";
1445                String text = "UIDs on the system are inconsistent, you need to wipe your"
1446                        + " data partition or your device will be unstable.";
1447                Log.e(TAG, title + ": " + text);
1448                if (mShowDialogs) {
1449                    // XXX This is a temporary dialog, no need to localize.
1450                    AlertDialog d = new BaseErrorDialog(mContext);
1451                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1452                    d.setCancelable(false);
1453                    d.setTitle(title);
1454                    d.setMessage(text);
1455                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1456                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1457                    mUidAlert = d;
1458                    d.show();
1459                }
1460            } break;
1461            case IM_FEELING_LUCKY_MSG: {
1462                if (mUidAlert != null) {
1463                    mUidAlert.dismiss();
1464                    mUidAlert = null;
1465                }
1466            } break;
1467            case PROC_START_TIMEOUT_MSG: {
1468                if (mDidDexOpt) {
1469                    mDidDexOpt = false;
1470                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1471                    nmsg.obj = msg.obj;
1472                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1473                    return;
1474                }
1475                ProcessRecord app = (ProcessRecord)msg.obj;
1476                synchronized (ActivityManagerService.this) {
1477                    processStartTimedOutLocked(app);
1478                }
1479            } break;
1480            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1481                synchronized (ActivityManagerService.this) {
1482                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1483                }
1484            } break;
1485            case KILL_APPLICATION_MSG: {
1486                synchronized (ActivityManagerService.this) {
1487                    int appid = msg.arg1;
1488                    boolean restart = (msg.arg2 == 1);
1489                    Bundle bundle = (Bundle)msg.obj;
1490                    String pkg = bundle.getString("pkg");
1491                    String reason = bundle.getString("reason");
1492                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1493                            false, UserHandle.USER_ALL, reason);
1494                }
1495            } break;
1496            case FINALIZE_PENDING_INTENT_MSG: {
1497                ((PendingIntentRecord)msg.obj).completeFinalize();
1498            } break;
1499            case POST_HEAVY_NOTIFICATION_MSG: {
1500                INotificationManager inm = NotificationManager.getService();
1501                if (inm == null) {
1502                    return;
1503                }
1504
1505                ActivityRecord root = (ActivityRecord)msg.obj;
1506                ProcessRecord process = root.app;
1507                if (process == null) {
1508                    return;
1509                }
1510
1511                try {
1512                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1513                    String text = mContext.getString(R.string.heavy_weight_notification,
1514                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1515                    Notification notification = new Notification();
1516                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1517                    notification.when = 0;
1518                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1519                    notification.tickerText = text;
1520                    notification.defaults = 0; // please be quiet
1521                    notification.sound = null;
1522                    notification.vibrate = null;
1523                    notification.color = mContext.getResources().getColor(
1524                            com.android.internal.R.color.system_notification_accent_color);
1525                    notification.setLatestEventInfo(context, text,
1526                            mContext.getText(R.string.heavy_weight_notification_detail),
1527                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1528                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1529                                    new UserHandle(root.userId)));
1530
1531                    try {
1532                        int[] outId = new int[1];
1533                        inm.enqueueNotificationWithTag("android", "android", null,
1534                                R.string.heavy_weight_notification,
1535                                notification, outId, root.userId);
1536                    } catch (RuntimeException e) {
1537                        Slog.w(ActivityManagerService.TAG,
1538                                "Error showing notification for heavy-weight app", e);
1539                    } catch (RemoteException e) {
1540                    }
1541                } catch (NameNotFoundException e) {
1542                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1543                }
1544            } break;
1545            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1546                INotificationManager inm = NotificationManager.getService();
1547                if (inm == null) {
1548                    return;
1549                }
1550                try {
1551                    inm.cancelNotificationWithTag("android", null,
1552                            R.string.heavy_weight_notification,  msg.arg1);
1553                } catch (RuntimeException e) {
1554                    Slog.w(ActivityManagerService.TAG,
1555                            "Error canceling notification for service", e);
1556                } catch (RemoteException e) {
1557                }
1558            } break;
1559            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1560                synchronized (ActivityManagerService.this) {
1561                    checkExcessivePowerUsageLocked(true);
1562                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1563                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1564                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1565                }
1566            } break;
1567            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1568                synchronized (ActivityManagerService.this) {
1569                    ActivityRecord ar = (ActivityRecord)msg.obj;
1570                    if (mCompatModeDialog != null) {
1571                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1572                                ar.info.applicationInfo.packageName)) {
1573                            return;
1574                        }
1575                        mCompatModeDialog.dismiss();
1576                        mCompatModeDialog = null;
1577                    }
1578                    if (ar != null && false) {
1579                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1580                                ar.packageName)) {
1581                            int mode = mCompatModePackages.computeCompatModeLocked(
1582                                    ar.info.applicationInfo);
1583                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1584                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1585                                mCompatModeDialog = new CompatModeDialog(
1586                                        ActivityManagerService.this, mContext,
1587                                        ar.info.applicationInfo);
1588                                mCompatModeDialog.show();
1589                            }
1590                        }
1591                    }
1592                }
1593                break;
1594            }
1595            case DISPATCH_PROCESSES_CHANGED: {
1596                dispatchProcessesChanged();
1597                break;
1598            }
1599            case DISPATCH_PROCESS_DIED: {
1600                final int pid = msg.arg1;
1601                final int uid = msg.arg2;
1602                dispatchProcessDied(pid, uid);
1603                break;
1604            }
1605            case REPORT_MEM_USAGE_MSG: {
1606                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1607                Thread thread = new Thread() {
1608                    @Override public void run() {
1609                        final SparseArray<ProcessMemInfo> infoMap
1610                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            infoMap.put(mi.pid, mi);
1614                        }
1615                        updateCpuStatsNow();
1616                        synchronized (mProcessCpuTracker) {
1617                            final int N = mProcessCpuTracker.countStats();
1618                            for (int i=0; i<N; i++) {
1619                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1620                                if (st.vsize > 0) {
1621                                    long pss = Debug.getPss(st.pid, null);
1622                                    if (pss > 0) {
1623                                        if (infoMap.indexOfKey(st.pid) < 0) {
1624                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1625                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1626                                            mi.pss = pss;
1627                                            memInfos.add(mi);
1628                                        }
1629                                    }
1630                                }
1631                            }
1632                        }
1633
1634                        long totalPss = 0;
1635                        for (int i=0, N=memInfos.size(); i<N; i++) {
1636                            ProcessMemInfo mi = memInfos.get(i);
1637                            if (mi.pss == 0) {
1638                                mi.pss = Debug.getPss(mi.pid, null);
1639                            }
1640                            totalPss += mi.pss;
1641                        }
1642                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1643                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1644                                if (lhs.oomAdj != rhs.oomAdj) {
1645                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1646                                }
1647                                if (lhs.pss != rhs.pss) {
1648                                    return lhs.pss < rhs.pss ? 1 : -1;
1649                                }
1650                                return 0;
1651                            }
1652                        });
1653
1654                        StringBuilder tag = new StringBuilder(128);
1655                        StringBuilder stack = new StringBuilder(128);
1656                        tag.append("Low on memory -- ");
1657                        appendMemBucket(tag, totalPss, "total", false);
1658                        appendMemBucket(stack, totalPss, "total", true);
1659
1660                        StringBuilder logBuilder = new StringBuilder(1024);
1661                        logBuilder.append("Low on memory:\n");
1662
1663                        boolean firstLine = true;
1664                        int lastOomAdj = Integer.MIN_VALUE;
1665                        for (int i=0, N=memInfos.size(); i<N; i++) {
1666                            ProcessMemInfo mi = memInfos.get(i);
1667
1668                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1669                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1670                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1671                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1672                                if (lastOomAdj != mi.oomAdj) {
1673                                    lastOomAdj = mi.oomAdj;
1674                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1675                                        tag.append(" / ");
1676                                    }
1677                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1678                                        if (firstLine) {
1679                                            stack.append(":");
1680                                            firstLine = false;
1681                                        }
1682                                        stack.append("\n\t at ");
1683                                    } else {
1684                                        stack.append("$");
1685                                    }
1686                                } else {
1687                                    tag.append(" ");
1688                                    stack.append("$");
1689                                }
1690                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1691                                    appendMemBucket(tag, mi.pss, mi.name, false);
1692                                }
1693                                appendMemBucket(stack, mi.pss, mi.name, true);
1694                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1695                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1696                                    stack.append("(");
1697                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1698                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1699                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1700                                            stack.append(":");
1701                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1702                                        }
1703                                    }
1704                                    stack.append(")");
1705                                }
1706                            }
1707
1708                            logBuilder.append("  ");
1709                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1710                            logBuilder.append(' ');
1711                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1712                            logBuilder.append(' ');
1713                            ProcessList.appendRamKb(logBuilder, mi.pss);
1714                            logBuilder.append(" kB: ");
1715                            logBuilder.append(mi.name);
1716                            logBuilder.append(" (");
1717                            logBuilder.append(mi.pid);
1718                            logBuilder.append(") ");
1719                            logBuilder.append(mi.adjType);
1720                            logBuilder.append('\n');
1721                            if (mi.adjReason != null) {
1722                                logBuilder.append("                      ");
1723                                logBuilder.append(mi.adjReason);
1724                                logBuilder.append('\n');
1725                            }
1726                        }
1727
1728                        logBuilder.append("           ");
1729                        ProcessList.appendRamKb(logBuilder, totalPss);
1730                        logBuilder.append(" kB: TOTAL\n");
1731
1732                        long[] infos = new long[Debug.MEMINFO_COUNT];
1733                        Debug.getMemInfo(infos);
1734                        logBuilder.append("  MemInfo: ");
1735                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1736                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1737                        logBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
1739                        logBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
1740                        logBuilder.append("           ");
1741                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1742                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1743                        logBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
1744                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1745                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1746                            logBuilder.append("  ZRAM: ");
1747                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1748                            logBuilder.append(" kB RAM, ");
1749                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1750                            logBuilder.append(" kB swap total, ");
1751                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1752                            logBuilder.append(" kB swap free\n");
1753                        }
1754                        Slog.i(TAG, logBuilder.toString());
1755
1756                        StringBuilder dropBuilder = new StringBuilder(1024);
1757                        /*
1758                        StringWriter oomSw = new StringWriter();
1759                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1760                        StringWriter catSw = new StringWriter();
1761                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1762                        String[] emptyArgs = new String[] { };
1763                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1764                        oomPw.flush();
1765                        String oomString = oomSw.toString();
1766                        */
1767                        dropBuilder.append(stack);
1768                        dropBuilder.append('\n');
1769                        dropBuilder.append('\n');
1770                        dropBuilder.append(logBuilder);
1771                        dropBuilder.append('\n');
1772                        /*
1773                        dropBuilder.append(oomString);
1774                        dropBuilder.append('\n');
1775                        */
1776                        StringWriter catSw = new StringWriter();
1777                        synchronized (ActivityManagerService.this) {
1778                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1779                            String[] emptyArgs = new String[] { };
1780                            catPw.println();
1781                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1782                            catPw.println();
1783                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1784                                    false, false, null);
1785                            catPw.println();
1786                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1787                            catPw.flush();
1788                        }
1789                        dropBuilder.append(catSw.toString());
1790                        addErrorToDropBox("lowmem", null, "system_server", null,
1791                                null, tag.toString(), dropBuilder.toString(), null, null);
1792                        //Slog.i(TAG, "Sent to dropbox:");
1793                        //Slog.i(TAG, dropBuilder.toString());
1794                        synchronized (ActivityManagerService.this) {
1795                            long now = SystemClock.uptimeMillis();
1796                            if (mLastMemUsageReportTime < now) {
1797                                mLastMemUsageReportTime = now;
1798                            }
1799                        }
1800                    }
1801                };
1802                thread.start();
1803                break;
1804            }
1805            case START_USER_SWITCH_MSG: {
1806                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1807                break;
1808            }
1809            case REPORT_USER_SWITCH_MSG: {
1810                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1811                break;
1812            }
1813            case CONTINUE_USER_SWITCH_MSG: {
1814                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1815                break;
1816            }
1817            case USER_SWITCH_TIMEOUT_MSG: {
1818                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1819                break;
1820            }
1821            case IMMERSIVE_MODE_LOCK_MSG: {
1822                final boolean nextState = (msg.arg1 != 0);
1823                if (mUpdateLock.isHeld() != nextState) {
1824                    if (DEBUG_IMMERSIVE) {
1825                        final ActivityRecord r = (ActivityRecord) msg.obj;
1826                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1827                    }
1828                    if (nextState) {
1829                        mUpdateLock.acquire();
1830                    } else {
1831                        mUpdateLock.release();
1832                    }
1833                }
1834                break;
1835            }
1836            case PERSIST_URI_GRANTS_MSG: {
1837                writeGrantedUriPermissions();
1838                break;
1839            }
1840            case REQUEST_ALL_PSS_MSG: {
1841                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1842                break;
1843            }
1844            case START_PROFILES_MSG: {
1845                synchronized (ActivityManagerService.this) {
1846                    startProfilesLocked();
1847                }
1848                break;
1849            }
1850            case UPDATE_TIME: {
1851                synchronized (ActivityManagerService.this) {
1852                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1853                        ProcessRecord r = mLruProcesses.get(i);
1854                        if (r.thread != null) {
1855                            try {
1856                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1857                            } catch (RemoteException ex) {
1858                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1859                            }
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case SYSTEM_USER_START_MSG: {
1866                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1867                        Integer.toString(msg.arg1), msg.arg1);
1868                mSystemServiceManager.startUser(msg.arg1);
1869                break;
1870            }
1871            case SYSTEM_USER_CURRENT_MSG: {
1872                mBatteryStatsService.noteEvent(
1873                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1874                        Integer.toString(msg.arg2), msg.arg2);
1875                mBatteryStatsService.noteEvent(
1876                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1877                        Integer.toString(msg.arg1), msg.arg1);
1878                mSystemServiceManager.switchUser(msg.arg1);
1879                mLockToAppRequest.clearPrompt();
1880                break;
1881            }
1882            case ENTER_ANIMATION_COMPLETE_MSG: {
1883                synchronized (ActivityManagerService.this) {
1884                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1885                    if (r != null && r.app != null && r.app.thread != null) {
1886                        try {
1887                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1888                        } catch (RemoteException e) {
1889                        }
1890                    }
1891                }
1892                break;
1893            }
1894            case FINISH_BOOTING_MSG: {
1895                if (msg.arg1 != 0) {
1896                    finishBooting();
1897                }
1898                if (msg.arg2 != 0) {
1899                    enableScreenAfterBoot();
1900                }
1901                break;
1902            }
1903            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1904                try {
1905                    Locale l = (Locale) msg.obj;
1906                    IBinder service = ServiceManager.getService("mount");
1907                    IMountService mountService = IMountService.Stub.asInterface(service);
1908                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1909                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1910                } catch (RemoteException e) {
1911                    Log.e(TAG, "Error storing locale for decryption UI", e);
1912                }
1913                break;
1914            }
1915            }
1916        }
1917    };
1918
1919    static final int COLLECT_PSS_BG_MSG = 1;
1920
1921    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1922        @Override
1923        public void handleMessage(Message msg) {
1924            switch (msg.what) {
1925            case COLLECT_PSS_BG_MSG: {
1926                long start = SystemClock.uptimeMillis();
1927                MemInfoReader memInfo = null;
1928                synchronized (ActivityManagerService.this) {
1929                    if (mFullPssPending) {
1930                        mFullPssPending = false;
1931                        memInfo = new MemInfoReader();
1932                    }
1933                }
1934                if (memInfo != null) {
1935                    updateCpuStatsNow();
1936                    long nativeTotalPss = 0;
1937                    synchronized (mProcessCpuTracker) {
1938                        final int N = mProcessCpuTracker.countStats();
1939                        for (int j=0; j<N; j++) {
1940                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1941                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1942                                // This is definitely an application process; skip it.
1943                                continue;
1944                            }
1945                            synchronized (mPidsSelfLocked) {
1946                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1947                                    // This is one of our own processes; skip it.
1948                                    continue;
1949                                }
1950                            }
1951                            nativeTotalPss += Debug.getPss(st.pid, null);
1952                        }
1953                    }
1954                    memInfo.readMemInfo();
1955                    synchronized (ActivityManagerService.this) {
1956                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1957                                + (SystemClock.uptimeMillis()-start) + "ms");
1958                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1959                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1960                                memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1961                    }
1962                }
1963
1964                int i=0, num=0;
1965                long[] tmp = new long[1];
1966                do {
1967                    ProcessRecord proc;
1968                    int procState;
1969                    int pid;
1970                    synchronized (ActivityManagerService.this) {
1971                        if (i >= mPendingPssProcesses.size()) {
1972                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1973                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1974                            mPendingPssProcesses.clear();
1975                            return;
1976                        }
1977                        proc = mPendingPssProcesses.get(i);
1978                        procState = proc.pssProcState;
1979                        if (proc.thread != null && procState == proc.setProcState) {
1980                            pid = proc.pid;
1981                        } else {
1982                            proc = null;
1983                            pid = 0;
1984                        }
1985                        i++;
1986                    }
1987                    if (proc != null) {
1988                        long pss = Debug.getPss(pid, tmp);
1989                        synchronized (ActivityManagerService.this) {
1990                            if (proc.thread != null && proc.setProcState == procState
1991                                    && proc.pid == pid) {
1992                                num++;
1993                                proc.lastPssTime = SystemClock.uptimeMillis();
1994                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1995                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1996                                        + ": " + pss + " lastPss=" + proc.lastPss
1997                                        + " state=" + ProcessList.makeProcStateString(procState));
1998                                if (proc.initialIdlePss == 0) {
1999                                    proc.initialIdlePss = pss;
2000                                }
2001                                proc.lastPss = pss;
2002                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2003                                    proc.lastCachedPss = pss;
2004                                }
2005                            }
2006                        }
2007                    }
2008                } while (true);
2009            }
2010            }
2011        }
2012    };
2013
2014    /**
2015     * Monitor for package changes and update our internal state.
2016     */
2017    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2018        @Override
2019        public void onPackageRemoved(String packageName, int uid) {
2020            // Remove all tasks with activities in the specified package from the list of recent tasks
2021            final int eventUserId = getChangingUserId();
2022            synchronized (ActivityManagerService.this) {
2023                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2024                    TaskRecord tr = mRecentTasks.get(i);
2025                    if (tr.userId != eventUserId) continue;
2026
2027                    ComponentName cn = tr.intent.getComponent();
2028                    if (cn != null && cn.getPackageName().equals(packageName)) {
2029                        // If the package name matches, remove the task and kill the process
2030                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2031                    }
2032                }
2033            }
2034        }
2035
2036        @Override
2037        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2038            onPackageModified(packageName);
2039            return true;
2040        }
2041
2042        @Override
2043        public void onPackageModified(String packageName) {
2044            final int eventUserId = getChangingUserId();
2045            final IPackageManager pm = AppGlobals.getPackageManager();
2046            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2047                    new ArrayList<Pair<Intent, Integer>>();
2048            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2049            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2050            // Copy the list of recent tasks so that we don't hold onto the lock on
2051            // ActivityManagerService for long periods while checking if components exist.
2052            synchronized (ActivityManagerService.this) {
2053                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2054                    TaskRecord tr = mRecentTasks.get(i);
2055                    if (tr.userId != eventUserId) continue;
2056
2057                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2058                }
2059            }
2060            // Check the recent tasks and filter out all tasks with components that no longer exist.
2061            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2062                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2063                ComponentName cn = p.first.getComponent();
2064                if (cn != null && cn.getPackageName().equals(packageName)) {
2065                    if (componentsKnownToExist.contains(cn)) {
2066                        // If we know that the component still exists in the package, then skip
2067                        continue;
2068                    }
2069                    try {
2070                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2071                        if (info != null) {
2072                            componentsKnownToExist.add(cn);
2073                        } else {
2074                            tasksToRemove.add(p.second);
2075                        }
2076                    } catch (RemoteException e) {
2077                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2078                    }
2079                }
2080            }
2081            // Prune all the tasks with removed components from the list of recent tasks
2082            synchronized (ActivityManagerService.this) {
2083                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2084                    // Remove the task but don't kill the process (since other components in that
2085                    // package may still be running and in the background)
2086                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2087                }
2088            }
2089        }
2090
2091        @Override
2092        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2093            // Force stop the specified packages
2094            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2095            if (packages != null) {
2096                for (String pkg : packages) {
2097                    synchronized (ActivityManagerService.this) {
2098                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2099                                userId, "finished booting")) {
2100                            return true;
2101                        }
2102                    }
2103                }
2104            }
2105            return false;
2106        }
2107    };
2108
2109    public void setSystemProcess() {
2110        try {
2111            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2112            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2113            ServiceManager.addService("meminfo", new MemBinder(this));
2114            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2115            ServiceManager.addService("dbinfo", new DbBinder(this));
2116            if (MONITOR_CPU_USAGE) {
2117                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2118            }
2119            ServiceManager.addService("permission", new PermissionController(this));
2120
2121            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2122                    "android", STOCK_PM_FLAGS);
2123            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2124
2125            synchronized (this) {
2126                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2127                app.persistent = true;
2128                app.pid = MY_PID;
2129                app.maxAdj = ProcessList.SYSTEM_ADJ;
2130                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2131                mProcessNames.put(app.processName, app.uid, app);
2132                synchronized (mPidsSelfLocked) {
2133                    mPidsSelfLocked.put(app.pid, app);
2134                }
2135                updateLruProcessLocked(app, false, null);
2136                updateOomAdjLocked();
2137            }
2138        } catch (PackageManager.NameNotFoundException e) {
2139            throw new RuntimeException(
2140                    "Unable to find android system package", e);
2141        }
2142    }
2143
2144    public void setWindowManager(WindowManagerService wm) {
2145        mWindowManager = wm;
2146        mStackSupervisor.setWindowManager(wm);
2147    }
2148
2149    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2150        mUsageStatsService = usageStatsManager;
2151    }
2152
2153    public void startObservingNativeCrashes() {
2154        final NativeCrashListener ncl = new NativeCrashListener(this);
2155        ncl.start();
2156    }
2157
2158    public IAppOpsService getAppOpsService() {
2159        return mAppOpsService;
2160    }
2161
2162    static class MemBinder extends Binder {
2163        ActivityManagerService mActivityManagerService;
2164        MemBinder(ActivityManagerService activityManagerService) {
2165            mActivityManagerService = activityManagerService;
2166        }
2167
2168        @Override
2169        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2170            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2171                    != PackageManager.PERMISSION_GRANTED) {
2172                pw.println("Permission Denial: can't dump meminfo from from pid="
2173                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2174                        + " without permission " + android.Manifest.permission.DUMP);
2175                return;
2176            }
2177
2178            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2179        }
2180    }
2181
2182    static class GraphicsBinder extends Binder {
2183        ActivityManagerService mActivityManagerService;
2184        GraphicsBinder(ActivityManagerService activityManagerService) {
2185            mActivityManagerService = activityManagerService;
2186        }
2187
2188        @Override
2189        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2190            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2191                    != PackageManager.PERMISSION_GRANTED) {
2192                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2193                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2194                        + " without permission " + android.Manifest.permission.DUMP);
2195                return;
2196            }
2197
2198            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2199        }
2200    }
2201
2202    static class DbBinder extends Binder {
2203        ActivityManagerService mActivityManagerService;
2204        DbBinder(ActivityManagerService activityManagerService) {
2205            mActivityManagerService = activityManagerService;
2206        }
2207
2208        @Override
2209        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2210            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2211                    != PackageManager.PERMISSION_GRANTED) {
2212                pw.println("Permission Denial: can't dump dbinfo from from pid="
2213                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2214                        + " without permission " + android.Manifest.permission.DUMP);
2215                return;
2216            }
2217
2218            mActivityManagerService.dumpDbInfo(fd, pw, args);
2219        }
2220    }
2221
2222    static class CpuBinder extends Binder {
2223        ActivityManagerService mActivityManagerService;
2224        CpuBinder(ActivityManagerService activityManagerService) {
2225            mActivityManagerService = activityManagerService;
2226        }
2227
2228        @Override
2229        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2230            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2231                    != PackageManager.PERMISSION_GRANTED) {
2232                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2233                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2234                        + " without permission " + android.Manifest.permission.DUMP);
2235                return;
2236            }
2237
2238            synchronized (mActivityManagerService.mProcessCpuTracker) {
2239                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2240                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2241                        SystemClock.uptimeMillis()));
2242            }
2243        }
2244    }
2245
2246    public static final class Lifecycle extends SystemService {
2247        private final ActivityManagerService mService;
2248
2249        public Lifecycle(Context context) {
2250            super(context);
2251            mService = new ActivityManagerService(context);
2252        }
2253
2254        @Override
2255        public void onStart() {
2256            mService.start();
2257        }
2258
2259        public ActivityManagerService getService() {
2260            return mService;
2261        }
2262    }
2263
2264    // Note: This method is invoked on the main thread but may need to attach various
2265    // handlers to other threads.  So take care to be explicit about the looper.
2266    public ActivityManagerService(Context systemContext) {
2267        mContext = systemContext;
2268        mFactoryTest = FactoryTest.getMode();
2269        mSystemThread = ActivityThread.currentActivityThread();
2270
2271        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2272
2273        mHandlerThread = new ServiceThread(TAG,
2274                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2275        mHandlerThread.start();
2276        mHandler = new MainHandler(mHandlerThread.getLooper());
2277
2278        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2279                "foreground", BROADCAST_FG_TIMEOUT, false);
2280        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2281                "background", BROADCAST_BG_TIMEOUT, true);
2282        mBroadcastQueues[0] = mFgBroadcastQueue;
2283        mBroadcastQueues[1] = mBgBroadcastQueue;
2284
2285        mServices = new ActiveServices(this);
2286        mProviderMap = new ProviderMap(this);
2287
2288        // TODO: Move creation of battery stats service outside of activity manager service.
2289        File dataDir = Environment.getDataDirectory();
2290        File systemDir = new File(dataDir, "system");
2291        systemDir.mkdirs();
2292        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2293        mBatteryStatsService.getActiveStatistics().readLocked();
2294        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2295        mOnBattery = DEBUG_POWER ? true
2296                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2297        mBatteryStatsService.getActiveStatistics().setCallback(this);
2298
2299        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2300
2301        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2302
2303        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2304
2305        // User 0 is the first and only user that runs at boot.
2306        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2307        mUserLru.add(Integer.valueOf(0));
2308        updateStartedUserArrayLocked();
2309
2310        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2311            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2312
2313        mConfiguration.setToDefaults();
2314        mConfiguration.setLocale(Locale.getDefault());
2315
2316        mConfigurationSeq = mConfiguration.seq = 1;
2317        mProcessCpuTracker.init();
2318
2319        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2320        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2321        mStackSupervisor = new ActivityStackSupervisor(this);
2322        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2323
2324        mProcessCpuThread = new Thread("CpuTracker") {
2325            @Override
2326            public void run() {
2327                while (true) {
2328                    try {
2329                        try {
2330                            synchronized(this) {
2331                                final long now = SystemClock.uptimeMillis();
2332                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2333                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2334                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2335                                //        + ", write delay=" + nextWriteDelay);
2336                                if (nextWriteDelay < nextCpuDelay) {
2337                                    nextCpuDelay = nextWriteDelay;
2338                                }
2339                                if (nextCpuDelay > 0) {
2340                                    mProcessCpuMutexFree.set(true);
2341                                    this.wait(nextCpuDelay);
2342                                }
2343                            }
2344                        } catch (InterruptedException e) {
2345                        }
2346                        updateCpuStatsNow();
2347                    } catch (Exception e) {
2348                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2349                    }
2350                }
2351            }
2352        };
2353
2354        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2355
2356        Watchdog.getInstance().addMonitor(this);
2357        Watchdog.getInstance().addThread(mHandler);
2358    }
2359
2360    public void setSystemServiceManager(SystemServiceManager mgr) {
2361        mSystemServiceManager = mgr;
2362    }
2363
2364    private void start() {
2365        Process.removeAllProcessGroups();
2366        mProcessCpuThread.start();
2367
2368        mBatteryStatsService.publish(mContext);
2369        mAppOpsService.publish(mContext);
2370        Slog.d("AppOps", "AppOpsService published");
2371        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2372    }
2373
2374    public void initPowerManagement() {
2375        mStackSupervisor.initPowerManagement();
2376        mBatteryStatsService.initPowerManagement();
2377    }
2378
2379    @Override
2380    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2381            throws RemoteException {
2382        if (code == SYSPROPS_TRANSACTION) {
2383            // We need to tell all apps about the system property change.
2384            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2385            synchronized(this) {
2386                final int NP = mProcessNames.getMap().size();
2387                for (int ip=0; ip<NP; ip++) {
2388                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2389                    final int NA = apps.size();
2390                    for (int ia=0; ia<NA; ia++) {
2391                        ProcessRecord app = apps.valueAt(ia);
2392                        if (app.thread != null) {
2393                            procs.add(app.thread.asBinder());
2394                        }
2395                    }
2396                }
2397            }
2398
2399            int N = procs.size();
2400            for (int i=0; i<N; i++) {
2401                Parcel data2 = Parcel.obtain();
2402                try {
2403                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2404                } catch (RemoteException e) {
2405                }
2406                data2.recycle();
2407            }
2408        }
2409        try {
2410            return super.onTransact(code, data, reply, flags);
2411        } catch (RuntimeException e) {
2412            // The activity manager only throws security exceptions, so let's
2413            // log all others.
2414            if (!(e instanceof SecurityException)) {
2415                Slog.wtf(TAG, "Activity Manager Crash", e);
2416            }
2417            throw e;
2418        }
2419    }
2420
2421    void updateCpuStats() {
2422        final long now = SystemClock.uptimeMillis();
2423        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2424            return;
2425        }
2426        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2427            synchronized (mProcessCpuThread) {
2428                mProcessCpuThread.notify();
2429            }
2430        }
2431    }
2432
2433    void updateCpuStatsNow() {
2434        synchronized (mProcessCpuTracker) {
2435            mProcessCpuMutexFree.set(false);
2436            final long now = SystemClock.uptimeMillis();
2437            boolean haveNewCpuStats = false;
2438
2439            if (MONITOR_CPU_USAGE &&
2440                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2441                mLastCpuTime.set(now);
2442                haveNewCpuStats = true;
2443                mProcessCpuTracker.update();
2444                //Slog.i(TAG, mProcessCpu.printCurrentState());
2445                //Slog.i(TAG, "Total CPU usage: "
2446                //        + mProcessCpu.getTotalCpuPercent() + "%");
2447
2448                // Slog the cpu usage if the property is set.
2449                if ("true".equals(SystemProperties.get("events.cpu"))) {
2450                    int user = mProcessCpuTracker.getLastUserTime();
2451                    int system = mProcessCpuTracker.getLastSystemTime();
2452                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2453                    int irq = mProcessCpuTracker.getLastIrqTime();
2454                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2455                    int idle = mProcessCpuTracker.getLastIdleTime();
2456
2457                    int total = user + system + iowait + irq + softIrq + idle;
2458                    if (total == 0) total = 1;
2459
2460                    EventLog.writeEvent(EventLogTags.CPU,
2461                            ((user+system+iowait+irq+softIrq) * 100) / total,
2462                            (user * 100) / total,
2463                            (system * 100) / total,
2464                            (iowait * 100) / total,
2465                            (irq * 100) / total,
2466                            (softIrq * 100) / total);
2467                }
2468            }
2469
2470            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2471            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2472            synchronized(bstats) {
2473                synchronized(mPidsSelfLocked) {
2474                    if (haveNewCpuStats) {
2475                        if (mOnBattery) {
2476                            int perc = bstats.startAddingCpuLocked();
2477                            int totalUTime = 0;
2478                            int totalSTime = 0;
2479                            final int N = mProcessCpuTracker.countStats();
2480                            for (int i=0; i<N; i++) {
2481                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2482                                if (!st.working) {
2483                                    continue;
2484                                }
2485                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2486                                int otherUTime = (st.rel_utime*perc)/100;
2487                                int otherSTime = (st.rel_stime*perc)/100;
2488                                totalUTime += otherUTime;
2489                                totalSTime += otherSTime;
2490                                if (pr != null) {
2491                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2492                                    if (ps == null || !ps.isActive()) {
2493                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2494                                                pr.info.uid, pr.processName);
2495                                    }
2496                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2497                                            st.rel_stime-otherSTime);
2498                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2499                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2500                                } else {
2501                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2502                                    if (ps == null || !ps.isActive()) {
2503                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2504                                                bstats.mapUid(st.uid), st.name);
2505                                    }
2506                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2507                                            st.rel_stime-otherSTime);
2508                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2509                                }
2510                            }
2511                            bstats.finishAddingCpuLocked(perc, totalUTime,
2512                                    totalSTime, cpuSpeedTimes);
2513                        }
2514                    }
2515                }
2516
2517                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2518                    mLastWriteTime = now;
2519                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2520                }
2521            }
2522        }
2523    }
2524
2525    @Override
2526    public void batteryNeedsCpuUpdate() {
2527        updateCpuStatsNow();
2528    }
2529
2530    @Override
2531    public void batteryPowerChanged(boolean onBattery) {
2532        // When plugging in, update the CPU stats first before changing
2533        // the plug state.
2534        updateCpuStatsNow();
2535        synchronized (this) {
2536            synchronized(mPidsSelfLocked) {
2537                mOnBattery = DEBUG_POWER ? true : onBattery;
2538            }
2539        }
2540    }
2541
2542    /**
2543     * Initialize the application bind args. These are passed to each
2544     * process when the bindApplication() IPC is sent to the process. They're
2545     * lazily setup to make sure the services are running when they're asked for.
2546     */
2547    private HashMap<String, IBinder> getCommonServicesLocked() {
2548        if (mAppBindArgs == null) {
2549            mAppBindArgs = new HashMap<String, IBinder>();
2550
2551            // Setup the application init args
2552            mAppBindArgs.put("package", ServiceManager.getService("package"));
2553            mAppBindArgs.put("window", ServiceManager.getService("window"));
2554            mAppBindArgs.put(Context.ALARM_SERVICE,
2555                    ServiceManager.getService(Context.ALARM_SERVICE));
2556        }
2557        return mAppBindArgs;
2558    }
2559
2560    final void setFocusedActivityLocked(ActivityRecord r) {
2561        if (mFocusedActivity != r) {
2562            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2563            mFocusedActivity = r;
2564            if (r.task != null && r.task.voiceInteractor != null) {
2565                startRunningVoiceLocked();
2566            } else {
2567                finishRunningVoiceLocked();
2568            }
2569            mStackSupervisor.setFocusedStack(r);
2570            if (r != null) {
2571                mWindowManager.setFocusedApp(r.appToken, true);
2572            }
2573            applyUpdateLockStateLocked(r);
2574        }
2575    }
2576
2577    final void clearFocusedActivity(ActivityRecord r) {
2578        if (mFocusedActivity == r) {
2579            mFocusedActivity = null;
2580        }
2581    }
2582
2583    @Override
2584    public void setFocusedStack(int stackId) {
2585        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2586        synchronized (ActivityManagerService.this) {
2587            ActivityStack stack = mStackSupervisor.getStack(stackId);
2588            if (stack != null) {
2589                ActivityRecord r = stack.topRunningActivityLocked(null);
2590                if (r != null) {
2591                    setFocusedActivityLocked(r);
2592                }
2593            }
2594        }
2595    }
2596
2597    @Override
2598    public void notifyActivityDrawn(IBinder token) {
2599        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2600        synchronized (this) {
2601            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2602            if (r != null) {
2603                r.task.stack.notifyActivityDrawnLocked(r);
2604            }
2605        }
2606    }
2607
2608    final void applyUpdateLockStateLocked(ActivityRecord r) {
2609        // Modifications to the UpdateLock state are done on our handler, outside
2610        // the activity manager's locks.  The new state is determined based on the
2611        // state *now* of the relevant activity record.  The object is passed to
2612        // the handler solely for logging detail, not to be consulted/modified.
2613        final boolean nextState = r != null && r.immersive;
2614        mHandler.sendMessage(
2615                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2616    }
2617
2618    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2619        Message msg = Message.obtain();
2620        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2621        msg.obj = r.task.askedCompatMode ? null : r;
2622        mHandler.sendMessage(msg);
2623    }
2624
2625    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2626            String what, Object obj, ProcessRecord srcApp) {
2627        app.lastActivityTime = now;
2628
2629        if (app.activities.size() > 0) {
2630            // Don't want to touch dependent processes that are hosting activities.
2631            return index;
2632        }
2633
2634        int lrui = mLruProcesses.lastIndexOf(app);
2635        if (lrui < 0) {
2636            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2637                    + what + " " + obj + " from " + srcApp);
2638            return index;
2639        }
2640
2641        if (lrui >= index) {
2642            // Don't want to cause this to move dependent processes *back* in the
2643            // list as if they were less frequently used.
2644            return index;
2645        }
2646
2647        if (lrui >= mLruProcessActivityStart) {
2648            // Don't want to touch dependent processes that are hosting activities.
2649            return index;
2650        }
2651
2652        mLruProcesses.remove(lrui);
2653        if (index > 0) {
2654            index--;
2655        }
2656        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2657                + " in LRU list: " + app);
2658        mLruProcesses.add(index, app);
2659        return index;
2660    }
2661
2662    final void removeLruProcessLocked(ProcessRecord app) {
2663        int lrui = mLruProcesses.lastIndexOf(app);
2664        if (lrui >= 0) {
2665            if (!app.killed) {
2666                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2667                Process.killProcessQuiet(app.pid);
2668                Process.killProcessGroup(app.info.uid, app.pid);
2669            }
2670            if (lrui <= mLruProcessActivityStart) {
2671                mLruProcessActivityStart--;
2672            }
2673            if (lrui <= mLruProcessServiceStart) {
2674                mLruProcessServiceStart--;
2675            }
2676            mLruProcesses.remove(lrui);
2677        }
2678    }
2679
2680    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2681            ProcessRecord client) {
2682        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2683                || app.treatLikeActivity;
2684        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2685        if (!activityChange && hasActivity) {
2686            // The process has activities, so we are only allowing activity-based adjustments
2687            // to move it.  It should be kept in the front of the list with other
2688            // processes that have activities, and we don't want those to change their
2689            // order except due to activity operations.
2690            return;
2691        }
2692
2693        mLruSeq++;
2694        final long now = SystemClock.uptimeMillis();
2695        app.lastActivityTime = now;
2696
2697        // First a quick reject: if the app is already at the position we will
2698        // put it, then there is nothing to do.
2699        if (hasActivity) {
2700            final int N = mLruProcesses.size();
2701            if (N > 0 && mLruProcesses.get(N-1) == app) {
2702                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2703                return;
2704            }
2705        } else {
2706            if (mLruProcessServiceStart > 0
2707                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2708                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2709                return;
2710            }
2711        }
2712
2713        int lrui = mLruProcesses.lastIndexOf(app);
2714
2715        if (app.persistent && lrui >= 0) {
2716            // We don't care about the position of persistent processes, as long as
2717            // they are in the list.
2718            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2719            return;
2720        }
2721
2722        /* In progress: compute new position first, so we can avoid doing work
2723           if the process is not actually going to move.  Not yet working.
2724        int addIndex;
2725        int nextIndex;
2726        boolean inActivity = false, inService = false;
2727        if (hasActivity) {
2728            // Process has activities, put it at the very tipsy-top.
2729            addIndex = mLruProcesses.size();
2730            nextIndex = mLruProcessServiceStart;
2731            inActivity = true;
2732        } else if (hasService) {
2733            // Process has services, put it at the top of the service list.
2734            addIndex = mLruProcessActivityStart;
2735            nextIndex = mLruProcessServiceStart;
2736            inActivity = true;
2737            inService = true;
2738        } else  {
2739            // Process not otherwise of interest, it goes to the top of the non-service area.
2740            addIndex = mLruProcessServiceStart;
2741            if (client != null) {
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2744                        + app);
2745                if (clientIndex >= 0 && addIndex > clientIndex) {
2746                    addIndex = clientIndex;
2747                }
2748            }
2749            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2750        }
2751
2752        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2753                + mLruProcessActivityStart + "): " + app);
2754        */
2755
2756        if (lrui >= 0) {
2757            if (lrui < mLruProcessActivityStart) {
2758                mLruProcessActivityStart--;
2759            }
2760            if (lrui < mLruProcessServiceStart) {
2761                mLruProcessServiceStart--;
2762            }
2763            /*
2764            if (addIndex > lrui) {
2765                addIndex--;
2766            }
2767            if (nextIndex > lrui) {
2768                nextIndex--;
2769            }
2770            */
2771            mLruProcesses.remove(lrui);
2772        }
2773
2774        /*
2775        mLruProcesses.add(addIndex, app);
2776        if (inActivity) {
2777            mLruProcessActivityStart++;
2778        }
2779        if (inService) {
2780            mLruProcessActivityStart++;
2781        }
2782        */
2783
2784        int nextIndex;
2785        if (hasActivity) {
2786            final int N = mLruProcesses.size();
2787            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2788                // Process doesn't have activities, but has clients with
2789                // activities...  move it up, but one below the top (the top
2790                // should always have a real activity).
2791                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2792                mLruProcesses.add(N-1, app);
2793                // To keep it from spamming the LRU list (by making a bunch of clients),
2794                // we will push down any other entries owned by the app.
2795                final int uid = app.info.uid;
2796                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2797                    ProcessRecord subProc = mLruProcesses.get(i);
2798                    if (subProc.info.uid == uid) {
2799                        // We want to push this one down the list.  If the process after
2800                        // it is for the same uid, however, don't do so, because we don't
2801                        // want them internally to be re-ordered.
2802                        if (mLruProcesses.get(i-1).info.uid != uid) {
2803                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2804                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2805                            ProcessRecord tmp = mLruProcesses.get(i);
2806                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2807                            mLruProcesses.set(i-1, tmp);
2808                            i--;
2809                        }
2810                    } else {
2811                        // A gap, we can stop here.
2812                        break;
2813                    }
2814                }
2815            } else {
2816                // Process has activities, put it at the very tipsy-top.
2817                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2818                mLruProcesses.add(app);
2819            }
2820            nextIndex = mLruProcessServiceStart;
2821        } else if (hasService) {
2822            // Process has services, put it at the top of the service list.
2823            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2824            mLruProcesses.add(mLruProcessActivityStart, app);
2825            nextIndex = mLruProcessServiceStart;
2826            mLruProcessActivityStart++;
2827        } else  {
2828            // Process not otherwise of interest, it goes to the top of the non-service area.
2829            int index = mLruProcessServiceStart;
2830            if (client != null) {
2831                // If there is a client, don't allow the process to be moved up higher
2832                // in the list than that client.
2833                int clientIndex = mLruProcesses.lastIndexOf(client);
2834                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2835                        + " when updating " + app);
2836                if (clientIndex <= lrui) {
2837                    // Don't allow the client index restriction to push it down farther in the
2838                    // list than it already is.
2839                    clientIndex = lrui;
2840                }
2841                if (clientIndex >= 0 && index > clientIndex) {
2842                    index = clientIndex;
2843                }
2844            }
2845            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2846            mLruProcesses.add(index, app);
2847            nextIndex = index-1;
2848            mLruProcessActivityStart++;
2849            mLruProcessServiceStart++;
2850        }
2851
2852        // If the app is currently using a content provider or service,
2853        // bump those processes as well.
2854        for (int j=app.connections.size()-1; j>=0; j--) {
2855            ConnectionRecord cr = app.connections.valueAt(j);
2856            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2857                    && cr.binding.service.app != null
2858                    && cr.binding.service.app.lruSeq != mLruSeq
2859                    && !cr.binding.service.app.persistent) {
2860                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2861                        "service connection", cr, app);
2862            }
2863        }
2864        for (int j=app.conProviders.size()-1; j>=0; j--) {
2865            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2866            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2867                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2868                        "provider reference", cpr, app);
2869            }
2870        }
2871    }
2872
2873    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2874        if (uid == Process.SYSTEM_UID) {
2875            // The system gets to run in any process.  If there are multiple
2876            // processes with the same uid, just pick the first (this
2877            // should never happen).
2878            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2879            if (procs == null) return null;
2880            final int N = procs.size();
2881            for (int i = 0; i < N; i++) {
2882                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2883            }
2884        }
2885        ProcessRecord proc = mProcessNames.get(processName, uid);
2886        if (false && proc != null && !keepIfLarge
2887                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2888                && proc.lastCachedPss >= 4000) {
2889            // Turn this condition on to cause killing to happen regularly, for testing.
2890            if (proc.baseProcessTracker != null) {
2891                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2892            }
2893            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2894        } else if (proc != null && !keepIfLarge
2895                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2896                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2897            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2898            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2899                if (proc.baseProcessTracker != null) {
2900                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2901                }
2902                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2903            }
2904        }
2905        return proc;
2906    }
2907
2908    void ensurePackageDexOpt(String packageName) {
2909        IPackageManager pm = AppGlobals.getPackageManager();
2910        try {
2911            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2912                mDidDexOpt = true;
2913            }
2914        } catch (RemoteException e) {
2915        }
2916    }
2917
2918    boolean isNextTransitionForward() {
2919        int transit = mWindowManager.getPendingAppTransition();
2920        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2921                || transit == AppTransition.TRANSIT_TASK_OPEN
2922                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2923    }
2924
2925    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2926            String processName, String abiOverride, int uid, Runnable crashHandler) {
2927        synchronized(this) {
2928            ApplicationInfo info = new ApplicationInfo();
2929            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2930            // For isolated processes, the former contains the parent's uid and the latter the
2931            // actual uid of the isolated process.
2932            // In the special case introduced by this method (which is, starting an isolated
2933            // process directly from the SystemServer without an actual parent app process) the
2934            // closest thing to a parent's uid is SYSTEM_UID.
2935            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2936            // the |isolated| logic in the ProcessRecord constructor.
2937            info.uid = Process.SYSTEM_UID;
2938            info.processName = processName;
2939            info.className = entryPoint;
2940            info.packageName = "android";
2941            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2942                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2943                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2944                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2945                    crashHandler);
2946            return proc != null ? proc.pid : 0;
2947        }
2948    }
2949
2950    final ProcessRecord startProcessLocked(String processName,
2951            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2952            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2953            boolean isolated, boolean keepIfLarge) {
2954        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2955                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2956                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2957                null /* crashHandler */);
2958    }
2959
2960    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2961            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2962            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2963            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2964        long startTime = SystemClock.elapsedRealtime();
2965        ProcessRecord app;
2966        if (!isolated) {
2967            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2968            checkTime(startTime, "startProcess: after getProcessRecord");
2969        } else {
2970            // If this is an isolated process, it can't re-use an existing process.
2971            app = null;
2972        }
2973        // We don't have to do anything more if:
2974        // (1) There is an existing application record; and
2975        // (2) The caller doesn't think it is dead, OR there is no thread
2976        //     object attached to it so we know it couldn't have crashed; and
2977        // (3) There is a pid assigned to it, so it is either starting or
2978        //     already running.
2979        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2980                + " app=" + app + " knownToBeDead=" + knownToBeDead
2981                + " thread=" + (app != null ? app.thread : null)
2982                + " pid=" + (app != null ? app.pid : -1));
2983        if (app != null && app.pid > 0) {
2984            if (!knownToBeDead || app.thread == null) {
2985                // We already have the app running, or are waiting for it to
2986                // come up (we have a pid but not yet its thread), so keep it.
2987                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2988                // If this is a new package in the process, add the package to the list
2989                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2990                checkTime(startTime, "startProcess: done, added package to proc");
2991                return app;
2992            }
2993
2994            // An application record is attached to a previous process,
2995            // clean it up now.
2996            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2997            checkTime(startTime, "startProcess: bad proc running, killing");
2998            Process.killProcessGroup(app.info.uid, app.pid);
2999            handleAppDiedLocked(app, true, true);
3000            checkTime(startTime, "startProcess: done killing old proc");
3001        }
3002
3003        String hostingNameStr = hostingName != null
3004                ? hostingName.flattenToShortString() : null;
3005
3006        if (!isolated) {
3007            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3008                // If we are in the background, then check to see if this process
3009                // is bad.  If so, we will just silently fail.
3010                if (mBadProcesses.get(info.processName, info.uid) != null) {
3011                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3012                            + "/" + info.processName);
3013                    return null;
3014                }
3015            } else {
3016                // When the user is explicitly starting a process, then clear its
3017                // crash count so that we won't make it bad until they see at
3018                // least one crash dialog again, and make the process good again
3019                // if it had been bad.
3020                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3021                        + "/" + info.processName);
3022                mProcessCrashTimes.remove(info.processName, info.uid);
3023                if (mBadProcesses.get(info.processName, info.uid) != null) {
3024                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3025                            UserHandle.getUserId(info.uid), info.uid,
3026                            info.processName);
3027                    mBadProcesses.remove(info.processName, info.uid);
3028                    if (app != null) {
3029                        app.bad = false;
3030                    }
3031                }
3032            }
3033        }
3034
3035        if (app == null) {
3036            checkTime(startTime, "startProcess: creating new process record");
3037            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3038            app.crashHandler = crashHandler;
3039            if (app == null) {
3040                Slog.w(TAG, "Failed making new process record for "
3041                        + processName + "/" + info.uid + " isolated=" + isolated);
3042                return null;
3043            }
3044            mProcessNames.put(processName, app.uid, app);
3045            if (isolated) {
3046                mIsolatedProcesses.put(app.uid, app);
3047            }
3048            checkTime(startTime, "startProcess: done creating new process record");
3049        } else {
3050            // If this is a new package in the process, add the package to the list
3051            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3052            checkTime(startTime, "startProcess: added package to existing proc");
3053        }
3054
3055        // If the system is not ready yet, then hold off on starting this
3056        // process until it is.
3057        if (!mProcessesReady
3058                && !isAllowedWhileBooting(info)
3059                && !allowWhileBooting) {
3060            if (!mProcessesOnHold.contains(app)) {
3061                mProcessesOnHold.add(app);
3062            }
3063            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3064            checkTime(startTime, "startProcess: returning with proc on hold");
3065            return app;
3066        }
3067
3068        checkTime(startTime, "startProcess: stepping in to startProcess");
3069        startProcessLocked(
3070                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3071        checkTime(startTime, "startProcess: done starting proc!");
3072        return (app.pid != 0) ? app : null;
3073    }
3074
3075    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3076        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3077    }
3078
3079    private final void startProcessLocked(ProcessRecord app,
3080            String hostingType, String hostingNameStr) {
3081        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3082                null /* entryPoint */, null /* entryPointArgs */);
3083    }
3084
3085    private final void startProcessLocked(ProcessRecord app, String hostingType,
3086            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3087        long startTime = SystemClock.elapsedRealtime();
3088        if (app.pid > 0 && app.pid != MY_PID) {
3089            checkTime(startTime, "startProcess: removing from pids map");
3090            synchronized (mPidsSelfLocked) {
3091                mPidsSelfLocked.remove(app.pid);
3092                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3093            }
3094            checkTime(startTime, "startProcess: done removing from pids map");
3095            app.setPid(0);
3096        }
3097
3098        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3099                "startProcessLocked removing on hold: " + app);
3100        mProcessesOnHold.remove(app);
3101
3102        checkTime(startTime, "startProcess: starting to update cpu stats");
3103        updateCpuStats();
3104        checkTime(startTime, "startProcess: done updating cpu stats");
3105
3106        try {
3107            int uid = app.uid;
3108
3109            int[] gids = null;
3110            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3111            if (!app.isolated) {
3112                int[] permGids = null;
3113                try {
3114                    checkTime(startTime, "startProcess: getting gids from package manager");
3115                    final PackageManager pm = mContext.getPackageManager();
3116                    permGids = pm.getPackageGids(app.info.packageName);
3117
3118                    if (Environment.isExternalStorageEmulated()) {
3119                        checkTime(startTime, "startProcess: checking external storage perm");
3120                        if (pm.checkPermission(
3121                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3122                                app.info.packageName) == PERMISSION_GRANTED) {
3123                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3124                        } else {
3125                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3126                        }
3127                    }
3128                } catch (PackageManager.NameNotFoundException e) {
3129                    Slog.w(TAG, "Unable to retrieve gids", e);
3130                }
3131
3132                /*
3133                 * Add shared application and profile GIDs so applications can share some
3134                 * resources like shared libraries and access user-wide resources
3135                 */
3136                if (permGids == null) {
3137                    gids = new int[2];
3138                } else {
3139                    gids = new int[permGids.length + 2];
3140                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3141                }
3142                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3143                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3144            }
3145            checkTime(startTime, "startProcess: building args");
3146            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3147                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3148                        && mTopComponent != null
3149                        && app.processName.equals(mTopComponent.getPackageName())) {
3150                    uid = 0;
3151                }
3152                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3153                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3154                    uid = 0;
3155                }
3156            }
3157            int debugFlags = 0;
3158            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3159                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3160                // Also turn on CheckJNI for debuggable apps. It's quite
3161                // awkward to turn on otherwise.
3162                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3163            }
3164            // Run the app in safe mode if its manifest requests so or the
3165            // system is booted in safe mode.
3166            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3167                mSafeMode == true) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3172            }
3173            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3174                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3175            }
3176            if ("1".equals(SystemProperties.get("debug.assert"))) {
3177                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3178            }
3179
3180            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3181            if (requiredAbi == null) {
3182                requiredAbi = Build.SUPPORTED_ABIS[0];
3183            }
3184
3185            String instructionSet = null;
3186            if (app.info.primaryCpuAbi != null) {
3187                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3188            }
3189
3190            // Start the process.  It will either succeed and return a result containing
3191            // the PID of the new process, or else throw a RuntimeException.
3192            boolean isActivityProcess = (entryPoint == null);
3193            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3194            checkTime(startTime, "startProcess: asking zygote to start proc");
3195            Process.ProcessStartResult startResult = Process.start(entryPoint,
3196                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3197                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3198                    app.info.dataDir, entryPointArgs);
3199            checkTime(startTime, "startProcess: returned from zygote!");
3200
3201            if (app.isolated) {
3202                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3203            }
3204            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3205            checkTime(startTime, "startProcess: done updating battery stats");
3206
3207            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3208                    UserHandle.getUserId(uid), startResult.pid, uid,
3209                    app.processName, hostingType,
3210                    hostingNameStr != null ? hostingNameStr : "");
3211
3212            if (app.persistent) {
3213                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3214            }
3215
3216            checkTime(startTime, "startProcess: building log message");
3217            StringBuilder buf = mStringBuilder;
3218            buf.setLength(0);
3219            buf.append("Start proc ");
3220            buf.append(app.processName);
3221            if (!isActivityProcess) {
3222                buf.append(" [");
3223                buf.append(entryPoint);
3224                buf.append("]");
3225            }
3226            buf.append(" for ");
3227            buf.append(hostingType);
3228            if (hostingNameStr != null) {
3229                buf.append(" ");
3230                buf.append(hostingNameStr);
3231            }
3232            buf.append(": pid=");
3233            buf.append(startResult.pid);
3234            buf.append(" uid=");
3235            buf.append(uid);
3236            buf.append(" gids={");
3237            if (gids != null) {
3238                for (int gi=0; gi<gids.length; gi++) {
3239                    if (gi != 0) buf.append(", ");
3240                    buf.append(gids[gi]);
3241
3242                }
3243            }
3244            buf.append("}");
3245            if (requiredAbi != null) {
3246                buf.append(" abi=");
3247                buf.append(requiredAbi);
3248            }
3249            Slog.i(TAG, buf.toString());
3250            app.setPid(startResult.pid);
3251            app.usingWrapper = startResult.usingWrapper;
3252            app.removed = false;
3253            app.killed = false;
3254            app.killedByAm = false;
3255            checkTime(startTime, "startProcess: starting to update pids map");
3256            synchronized (mPidsSelfLocked) {
3257                this.mPidsSelfLocked.put(startResult.pid, app);
3258                if (isActivityProcess) {
3259                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3260                    msg.obj = app;
3261                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3262                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3263                }
3264            }
3265            checkTime(startTime, "startProcess: done updating pids map");
3266        } catch (RuntimeException e) {
3267            // XXX do better error recovery.
3268            app.setPid(0);
3269            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3270            if (app.isolated) {
3271                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3272            }
3273            Slog.e(TAG, "Failure starting process " + app.processName, e);
3274        }
3275    }
3276
3277    void updateUsageStats(ActivityRecord component, boolean resumed) {
3278        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3279        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3280        if (resumed) {
3281            if (mUsageStatsService != null) {
3282                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3283                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3284            }
3285            synchronized (stats) {
3286                stats.noteActivityResumedLocked(component.app.uid);
3287            }
3288        } else {
3289            if (mUsageStatsService != null) {
3290                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3291                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3292            }
3293            synchronized (stats) {
3294                stats.noteActivityPausedLocked(component.app.uid);
3295            }
3296        }
3297    }
3298
3299    Intent getHomeIntent() {
3300        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3301        intent.setComponent(mTopComponent);
3302        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3303            intent.addCategory(Intent.CATEGORY_HOME);
3304        }
3305        return intent;
3306    }
3307
3308    boolean startHomeActivityLocked(int userId) {
3309        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3310                && mTopAction == null) {
3311            // We are running in factory test mode, but unable to find
3312            // the factory test app, so just sit around displaying the
3313            // error message and don't try to start anything.
3314            return false;
3315        }
3316        Intent intent = getHomeIntent();
3317        ActivityInfo aInfo =
3318            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3319        if (aInfo != null) {
3320            intent.setComponent(new ComponentName(
3321                    aInfo.applicationInfo.packageName, aInfo.name));
3322            // Don't do this if the home app is currently being
3323            // instrumented.
3324            aInfo = new ActivityInfo(aInfo);
3325            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3326            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3327                    aInfo.applicationInfo.uid, true);
3328            if (app == null || app.instrumentationClass == null) {
3329                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3330                mStackSupervisor.startHomeActivity(intent, aInfo);
3331            }
3332        }
3333
3334        return true;
3335    }
3336
3337    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3338        ActivityInfo ai = null;
3339        ComponentName comp = intent.getComponent();
3340        try {
3341            if (comp != null) {
3342                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3343            } else {
3344                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3345                        intent,
3346                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3347                            flags, userId);
3348
3349                if (info != null) {
3350                    ai = info.activityInfo;
3351                }
3352            }
3353        } catch (RemoteException e) {
3354            // ignore
3355        }
3356
3357        return ai;
3358    }
3359
3360    /**
3361     * Starts the "new version setup screen" if appropriate.
3362     */
3363    void startSetupActivityLocked() {
3364        // Only do this once per boot.
3365        if (mCheckedForSetup) {
3366            return;
3367        }
3368
3369        // We will show this screen if the current one is a different
3370        // version than the last one shown, and we are not running in
3371        // low-level factory test mode.
3372        final ContentResolver resolver = mContext.getContentResolver();
3373        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3374                Settings.Global.getInt(resolver,
3375                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3376            mCheckedForSetup = true;
3377
3378            // See if we should be showing the platform update setup UI.
3379            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3380            List<ResolveInfo> ris = mContext.getPackageManager()
3381                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3382
3383            // We don't allow third party apps to replace this.
3384            ResolveInfo ri = null;
3385            for (int i=0; ris != null && i<ris.size(); i++) {
3386                if ((ris.get(i).activityInfo.applicationInfo.flags
3387                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3388                    ri = ris.get(i);
3389                    break;
3390                }
3391            }
3392
3393            if (ri != null) {
3394                String vers = ri.activityInfo.metaData != null
3395                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3396                        : null;
3397                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3398                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3399                            Intent.METADATA_SETUP_VERSION);
3400                }
3401                String lastVers = Settings.Secure.getString(
3402                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3403                if (vers != null && !vers.equals(lastVers)) {
3404                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3405                    intent.setComponent(new ComponentName(
3406                            ri.activityInfo.packageName, ri.activityInfo.name));
3407                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3408                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3409                            null);
3410                }
3411            }
3412        }
3413    }
3414
3415    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3416        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3417    }
3418
3419    void enforceNotIsolatedCaller(String caller) {
3420        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3421            throw new SecurityException("Isolated process not allowed to call " + caller);
3422        }
3423    }
3424
3425    void enforceShellRestriction(String restriction, int userHandle) {
3426        if (Binder.getCallingUid() == Process.SHELL_UID) {
3427            if (userHandle < 0
3428                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3429                throw new SecurityException("Shell does not have permission to access user "
3430                        + userHandle);
3431            }
3432        }
3433    }
3434
3435    @Override
3436    public int getFrontActivityScreenCompatMode() {
3437        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3438        synchronized (this) {
3439            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3440        }
3441    }
3442
3443    @Override
3444    public void setFrontActivityScreenCompatMode(int mode) {
3445        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3446                "setFrontActivityScreenCompatMode");
3447        synchronized (this) {
3448            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3449        }
3450    }
3451
3452    @Override
3453    public int getPackageScreenCompatMode(String packageName) {
3454        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3455        synchronized (this) {
3456            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3457        }
3458    }
3459
3460    @Override
3461    public void setPackageScreenCompatMode(String packageName, int mode) {
3462        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3463                "setPackageScreenCompatMode");
3464        synchronized (this) {
3465            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3466        }
3467    }
3468
3469    @Override
3470    public boolean getPackageAskScreenCompat(String packageName) {
3471        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3472        synchronized (this) {
3473            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3474        }
3475    }
3476
3477    @Override
3478    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3479        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3480                "setPackageAskScreenCompat");
3481        synchronized (this) {
3482            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3483        }
3484    }
3485
3486    private void dispatchProcessesChanged() {
3487        int N;
3488        synchronized (this) {
3489            N = mPendingProcessChanges.size();
3490            if (mActiveProcessChanges.length < N) {
3491                mActiveProcessChanges = new ProcessChangeItem[N];
3492            }
3493            mPendingProcessChanges.toArray(mActiveProcessChanges);
3494            mAvailProcessChanges.addAll(mPendingProcessChanges);
3495            mPendingProcessChanges.clear();
3496            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3497        }
3498
3499        int i = mProcessObservers.beginBroadcast();
3500        while (i > 0) {
3501            i--;
3502            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3503            if (observer != null) {
3504                try {
3505                    for (int j=0; j<N; j++) {
3506                        ProcessChangeItem item = mActiveProcessChanges[j];
3507                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3508                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3509                                    + item.pid + " uid=" + item.uid + ": "
3510                                    + item.foregroundActivities);
3511                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3512                                    item.foregroundActivities);
3513                        }
3514                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3515                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3516                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3517                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3518                        }
3519                    }
3520                } catch (RemoteException e) {
3521                }
3522            }
3523        }
3524        mProcessObservers.finishBroadcast();
3525    }
3526
3527    private void dispatchProcessDied(int pid, int uid) {
3528        int i = mProcessObservers.beginBroadcast();
3529        while (i > 0) {
3530            i--;
3531            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3532            if (observer != null) {
3533                try {
3534                    observer.onProcessDied(pid, uid);
3535                } catch (RemoteException e) {
3536                }
3537            }
3538        }
3539        mProcessObservers.finishBroadcast();
3540    }
3541
3542    @Override
3543    public final int startActivity(IApplicationThread caller, String callingPackage,
3544            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3545            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3546        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3547            resultWho, requestCode, startFlags, profilerInfo, options,
3548            UserHandle.getCallingUserId());
3549    }
3550
3551    @Override
3552    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3553            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3554            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3555        enforceNotIsolatedCaller("startActivity");
3556        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3557                false, ALLOW_FULL_ONLY, "startActivity", null);
3558        // TODO: Switch to user app stacks here.
3559        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3560                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3561                profilerInfo, null, null, options, userId, null, null);
3562    }
3563
3564    @Override
3565    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3566            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3567            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3568
3569        // This is very dangerous -- it allows you to perform a start activity (including
3570        // permission grants) as any app that may launch one of your own activities.  So
3571        // we will only allow this to be done from activities that are part of the core framework,
3572        // and then only when they are running as the system.
3573        final ActivityRecord sourceRecord;
3574        final int targetUid;
3575        final String targetPackage;
3576        synchronized (this) {
3577            if (resultTo == null) {
3578                throw new SecurityException("Must be called from an activity");
3579            }
3580            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3581            if (sourceRecord == null) {
3582                throw new SecurityException("Called with bad activity token: " + resultTo);
3583            }
3584            if (!sourceRecord.info.packageName.equals("android")) {
3585                throw new SecurityException(
3586                        "Must be called from an activity that is declared in the android package");
3587            }
3588            if (sourceRecord.app == null) {
3589                throw new SecurityException("Called without a process attached to activity");
3590            }
3591            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3592                // This is still okay, as long as this activity is running under the
3593                // uid of the original calling activity.
3594                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3595                    throw new SecurityException(
3596                            "Calling activity in uid " + sourceRecord.app.uid
3597                                    + " must be system uid or original calling uid "
3598                                    + sourceRecord.launchedFromUid);
3599                }
3600            }
3601            targetUid = sourceRecord.launchedFromUid;
3602            targetPackage = sourceRecord.launchedFromPackage;
3603        }
3604
3605        if (userId == UserHandle.USER_NULL) {
3606            userId = UserHandle.getUserId(sourceRecord.app.uid);
3607        }
3608
3609        // TODO: Switch to user app stacks here.
3610        try {
3611            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3612                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3613                    null, null, options, userId, null, null);
3614            return ret;
3615        } catch (SecurityException e) {
3616            // XXX need to figure out how to propagate to original app.
3617            // A SecurityException here is generally actually a fault of the original
3618            // calling activity (such as a fairly granting permissions), so propagate it
3619            // back to them.
3620            /*
3621            StringBuilder msg = new StringBuilder();
3622            msg.append("While launching");
3623            msg.append(intent.toString());
3624            msg.append(": ");
3625            msg.append(e.getMessage());
3626            */
3627            throw e;
3628        }
3629    }
3630
3631    @Override
3632    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3633            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3634            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3635        enforceNotIsolatedCaller("startActivityAndWait");
3636        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3637                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3638        WaitResult res = new WaitResult();
3639        // TODO: Switch to user app stacks here.
3640        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3641                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3642                options, userId, null, null);
3643        return res;
3644    }
3645
3646    @Override
3647    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3648            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3649            int startFlags, Configuration config, Bundle options, int userId) {
3650        enforceNotIsolatedCaller("startActivityWithConfig");
3651        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3652                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3653        // TODO: Switch to user app stacks here.
3654        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3655                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3656                null, null, config, options, userId, null, null);
3657        return ret;
3658    }
3659
3660    @Override
3661    public int startActivityIntentSender(IApplicationThread caller,
3662            IntentSender intent, Intent fillInIntent, String resolvedType,
3663            IBinder resultTo, String resultWho, int requestCode,
3664            int flagsMask, int flagsValues, Bundle options) {
3665        enforceNotIsolatedCaller("startActivityIntentSender");
3666        // Refuse possible leaked file descriptors
3667        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3668            throw new IllegalArgumentException("File descriptors passed in Intent");
3669        }
3670
3671        IIntentSender sender = intent.getTarget();
3672        if (!(sender instanceof PendingIntentRecord)) {
3673            throw new IllegalArgumentException("Bad PendingIntent object");
3674        }
3675
3676        PendingIntentRecord pir = (PendingIntentRecord)sender;
3677
3678        synchronized (this) {
3679            // If this is coming from the currently resumed activity, it is
3680            // effectively saying that app switches are allowed at this point.
3681            final ActivityStack stack = getFocusedStack();
3682            if (stack.mResumedActivity != null &&
3683                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3684                mAppSwitchesAllowedTime = 0;
3685            }
3686        }
3687        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3688                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3689        return ret;
3690    }
3691
3692    @Override
3693    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3694            Intent intent, String resolvedType, IVoiceInteractionSession session,
3695            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3696            Bundle options, int userId) {
3697        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3698                != PackageManager.PERMISSION_GRANTED) {
3699            String msg = "Permission Denial: startVoiceActivity() from pid="
3700                    + Binder.getCallingPid()
3701                    + ", uid=" + Binder.getCallingUid()
3702                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3703            Slog.w(TAG, msg);
3704            throw new SecurityException(msg);
3705        }
3706        if (session == null || interactor == null) {
3707            throw new NullPointerException("null session or interactor");
3708        }
3709        userId = handleIncomingUser(callingPid, callingUid, userId,
3710                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3711        // TODO: Switch to user app stacks here.
3712        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3713                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3714                null, options, userId, null, null);
3715    }
3716
3717    @Override
3718    public boolean startNextMatchingActivity(IBinder callingActivity,
3719            Intent intent, Bundle options) {
3720        // Refuse possible leaked file descriptors
3721        if (intent != null && intent.hasFileDescriptors() == true) {
3722            throw new IllegalArgumentException("File descriptors passed in Intent");
3723        }
3724
3725        synchronized (this) {
3726            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3727            if (r == null) {
3728                ActivityOptions.abort(options);
3729                return false;
3730            }
3731            if (r.app == null || r.app.thread == null) {
3732                // The caller is not running...  d'oh!
3733                ActivityOptions.abort(options);
3734                return false;
3735            }
3736            intent = new Intent(intent);
3737            // The caller is not allowed to change the data.
3738            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3739            // And we are resetting to find the next component...
3740            intent.setComponent(null);
3741
3742            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3743
3744            ActivityInfo aInfo = null;
3745            try {
3746                List<ResolveInfo> resolves =
3747                    AppGlobals.getPackageManager().queryIntentActivities(
3748                            intent, r.resolvedType,
3749                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3750                            UserHandle.getCallingUserId());
3751
3752                // Look for the original activity in the list...
3753                final int N = resolves != null ? resolves.size() : 0;
3754                for (int i=0; i<N; i++) {
3755                    ResolveInfo rInfo = resolves.get(i);
3756                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3757                            && rInfo.activityInfo.name.equals(r.info.name)) {
3758                        // We found the current one...  the next matching is
3759                        // after it.
3760                        i++;
3761                        if (i<N) {
3762                            aInfo = resolves.get(i).activityInfo;
3763                        }
3764                        if (debug) {
3765                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3766                                    + "/" + r.info.name);
3767                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3768                                    + "/" + aInfo.name);
3769                        }
3770                        break;
3771                    }
3772                }
3773            } catch (RemoteException e) {
3774            }
3775
3776            if (aInfo == null) {
3777                // Nobody who is next!
3778                ActivityOptions.abort(options);
3779                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3780                return false;
3781            }
3782
3783            intent.setComponent(new ComponentName(
3784                    aInfo.applicationInfo.packageName, aInfo.name));
3785            intent.setFlags(intent.getFlags()&~(
3786                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3787                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3788                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3789                    Intent.FLAG_ACTIVITY_NEW_TASK));
3790
3791            // Okay now we need to start the new activity, replacing the
3792            // currently running activity.  This is a little tricky because
3793            // we want to start the new one as if the current one is finished,
3794            // but not finish the current one first so that there is no flicker.
3795            // And thus...
3796            final boolean wasFinishing = r.finishing;
3797            r.finishing = true;
3798
3799            // Propagate reply information over to the new activity.
3800            final ActivityRecord resultTo = r.resultTo;
3801            final String resultWho = r.resultWho;
3802            final int requestCode = r.requestCode;
3803            r.resultTo = null;
3804            if (resultTo != null) {
3805                resultTo.removeResultsLocked(r, resultWho, requestCode);
3806            }
3807
3808            final long origId = Binder.clearCallingIdentity();
3809            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3810                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3811                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3812                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3813            Binder.restoreCallingIdentity(origId);
3814
3815            r.finishing = wasFinishing;
3816            if (res != ActivityManager.START_SUCCESS) {
3817                return false;
3818            }
3819            return true;
3820        }
3821    }
3822
3823    @Override
3824    public final int startActivityFromRecents(int taskId, Bundle options) {
3825        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3826            String msg = "Permission Denial: startActivityFromRecents called without " +
3827                    START_TASKS_FROM_RECENTS;
3828            Slog.w(TAG, msg);
3829            throw new SecurityException(msg);
3830        }
3831        return startActivityFromRecentsInner(taskId, options);
3832    }
3833
3834    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3835        final TaskRecord task;
3836        final int callingUid;
3837        final String callingPackage;
3838        final Intent intent;
3839        final int userId;
3840        synchronized (this) {
3841            task = recentTaskForIdLocked(taskId);
3842            if (task == null) {
3843                throw new IllegalArgumentException("Task " + taskId + " not found.");
3844            }
3845            callingUid = task.mCallingUid;
3846            callingPackage = task.mCallingPackage;
3847            intent = task.intent;
3848            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3849            userId = task.userId;
3850        }
3851        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3852                options, userId, null, task);
3853    }
3854
3855    final int startActivityInPackage(int uid, String callingPackage,
3856            Intent intent, String resolvedType, IBinder resultTo,
3857            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3858            IActivityContainer container, TaskRecord inTask) {
3859
3860        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3861                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3862
3863        // TODO: Switch to user app stacks here.
3864        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3865                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3866                null, null, null, options, userId, container, inTask);
3867        return ret;
3868    }
3869
3870    @Override
3871    public final int startActivities(IApplicationThread caller, String callingPackage,
3872            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3873            int userId) {
3874        enforceNotIsolatedCaller("startActivities");
3875        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3876                false, ALLOW_FULL_ONLY, "startActivity", null);
3877        // TODO: Switch to user app stacks here.
3878        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3879                resolvedTypes, resultTo, options, userId);
3880        return ret;
3881    }
3882
3883    final int startActivitiesInPackage(int uid, String callingPackage,
3884            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3885            Bundle options, int userId) {
3886
3887        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3888                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3889        // TODO: Switch to user app stacks here.
3890        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3891                resultTo, options, userId);
3892        return ret;
3893    }
3894
3895    //explicitly remove thd old information in mRecentTasks when removing existing user.
3896    private void removeRecentTasksForUserLocked(int userId) {
3897        if(userId <= 0) {
3898            Slog.i(TAG, "Can't remove recent task on user " + userId);
3899            return;
3900        }
3901
3902        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3903            TaskRecord tr = mRecentTasks.get(i);
3904            if (tr.userId == userId) {
3905                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3906                        + " when finishing user" + userId);
3907                mRecentTasks.remove(i);
3908                tr.removedFromRecents(mTaskPersister);
3909            }
3910        }
3911
3912        // Remove tasks from persistent storage.
3913        mTaskPersister.wakeup(null, true);
3914    }
3915
3916    // Sort by taskId
3917    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3918        @Override
3919        public int compare(TaskRecord lhs, TaskRecord rhs) {
3920            return rhs.taskId - lhs.taskId;
3921        }
3922    };
3923
3924    // Extract the affiliates of the chain containing mRecentTasks[start].
3925    private int processNextAffiliateChain(int start) {
3926        final TaskRecord startTask = mRecentTasks.get(start);
3927        final int affiliateId = startTask.mAffiliatedTaskId;
3928
3929        // Quick identification of isolated tasks. I.e. those not launched behind.
3930        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3931                startTask.mNextAffiliate == null) {
3932            // There is still a slim chance that there are other tasks that point to this task
3933            // and that the chain is so messed up that this task no longer points to them but
3934            // the gain of this optimization outweighs the risk.
3935            startTask.inRecents = true;
3936            return start + 1;
3937        }
3938
3939        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3940        mTmpRecents.clear();
3941        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3942            final TaskRecord task = mRecentTasks.get(i);
3943            if (task.mAffiliatedTaskId == affiliateId) {
3944                mRecentTasks.remove(i);
3945                mTmpRecents.add(task);
3946            }
3947        }
3948
3949        // Sort them all by taskId. That is the order they were create in and that order will
3950        // always be correct.
3951        Collections.sort(mTmpRecents, mTaskRecordComparator);
3952
3953        // Go through and fix up the linked list.
3954        // The first one is the end of the chain and has no next.
3955        final TaskRecord first = mTmpRecents.get(0);
3956        first.inRecents = true;
3957        if (first.mNextAffiliate != null) {
3958            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3959            first.setNextAffiliate(null);
3960            mTaskPersister.wakeup(first, false);
3961        }
3962        // Everything in the middle is doubly linked from next to prev.
3963        final int tmpSize = mTmpRecents.size();
3964        for (int i = 0; i < tmpSize - 1; ++i) {
3965            final TaskRecord next = mTmpRecents.get(i);
3966            final TaskRecord prev = mTmpRecents.get(i + 1);
3967            if (next.mPrevAffiliate != prev) {
3968                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3969                        " setting prev=" + prev);
3970                next.setPrevAffiliate(prev);
3971                mTaskPersister.wakeup(next, false);
3972            }
3973            if (prev.mNextAffiliate != next) {
3974                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3975                        " setting next=" + next);
3976                prev.setNextAffiliate(next);
3977                mTaskPersister.wakeup(prev, false);
3978            }
3979            prev.inRecents = true;
3980        }
3981        // The last one is the beginning of the list and has no prev.
3982        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3983        if (last.mPrevAffiliate != null) {
3984            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3985            last.setPrevAffiliate(null);
3986            mTaskPersister.wakeup(last, false);
3987        }
3988
3989        // Insert the group back into mRecentTasks at start.
3990        mRecentTasks.addAll(start, mTmpRecents);
3991
3992        // Let the caller know where we left off.
3993        return start + tmpSize;
3994    }
3995
3996    /**
3997     * Update the recent tasks lists: make sure tasks should still be here (their
3998     * applications / activities still exist), update their availability, fixup ordering
3999     * of affiliations.
4000     */
4001    void cleanupRecentTasksLocked(int userId) {
4002        if (mRecentTasks == null) {
4003            // Happens when called from the packagemanager broadcast before boot.
4004            return;
4005        }
4006
4007        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4008        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4009        final IPackageManager pm = AppGlobals.getPackageManager();
4010        final ActivityInfo dummyAct = new ActivityInfo();
4011        final ApplicationInfo dummyApp = new ApplicationInfo();
4012
4013        int N = mRecentTasks.size();
4014
4015        int[] users = userId == UserHandle.USER_ALL
4016                ? getUsersLocked() : new int[] { userId };
4017        for (int user : users) {
4018            for (int i = 0; i < N; i++) {
4019                TaskRecord task = mRecentTasks.get(i);
4020                if (task.userId != user) {
4021                    // Only look at tasks for the user ID of interest.
4022                    continue;
4023                }
4024                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4025                    // This situation is broken, and we should just get rid of it now.
4026                    mRecentTasks.remove(i);
4027                    task.removedFromRecents(mTaskPersister);
4028                    i--;
4029                    N--;
4030                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4031                    continue;
4032                }
4033                // Check whether this activity is currently available.
4034                if (task.realActivity != null) {
4035                    ActivityInfo ai = availActCache.get(task.realActivity);
4036                    if (ai == null) {
4037                        try {
4038                            ai = pm.getActivityInfo(task.realActivity,
4039                                    PackageManager.GET_UNINSTALLED_PACKAGES
4040                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4041                        } catch (RemoteException e) {
4042                            // Will never happen.
4043                            continue;
4044                        }
4045                        if (ai == null) {
4046                            ai = dummyAct;
4047                        }
4048                        availActCache.put(task.realActivity, ai);
4049                    }
4050                    if (ai == dummyAct) {
4051                        // This could be either because the activity no longer exists, or the
4052                        // app is temporarily gone.  For the former we want to remove the recents
4053                        // entry; for the latter we want to mark it as unavailable.
4054                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4055                        if (app == null) {
4056                            try {
4057                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4058                                        PackageManager.GET_UNINSTALLED_PACKAGES
4059                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4060                            } catch (RemoteException e) {
4061                                // Will never happen.
4062                                continue;
4063                            }
4064                            if (app == null) {
4065                                app = dummyApp;
4066                            }
4067                            availAppCache.put(task.realActivity.getPackageName(), app);
4068                        }
4069                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4070                            // Doesn't exist any more!  Good-bye.
4071                            mRecentTasks.remove(i);
4072                            task.removedFromRecents(mTaskPersister);
4073                            i--;
4074                            N--;
4075                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4076                            continue;
4077                        } else {
4078                            // Otherwise just not available for now.
4079                            if (task.isAvailable) {
4080                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4081                                        + task);
4082                            }
4083                            task.isAvailable = false;
4084                        }
4085                    } else {
4086                        if (!ai.enabled || !ai.applicationInfo.enabled
4087                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4088                            if (task.isAvailable) {
4089                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4090                                        + task + " (enabled=" + ai.enabled + "/"
4091                                        + ai.applicationInfo.enabled +  " flags="
4092                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4093                            }
4094                            task.isAvailable = false;
4095                        } else {
4096                            if (!task.isAvailable) {
4097                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4098                                        + task);
4099                            }
4100                            task.isAvailable = true;
4101                        }
4102                    }
4103                }
4104            }
4105        }
4106
4107        // Verify the affiliate chain for each task.
4108        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4109        }
4110
4111        mTmpRecents.clear();
4112        // mRecentTasks is now in sorted, affiliated order.
4113    }
4114
4115    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4116        int N = mRecentTasks.size();
4117        TaskRecord top = task;
4118        int topIndex = taskIndex;
4119        while (top.mNextAffiliate != null && topIndex > 0) {
4120            top = top.mNextAffiliate;
4121            topIndex--;
4122        }
4123        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4124                + topIndex + " from intial " + taskIndex);
4125        // Find the end of the chain, doing a sanity check along the way.
4126        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4127        int endIndex = topIndex;
4128        TaskRecord prev = top;
4129        while (endIndex < N) {
4130            TaskRecord cur = mRecentTasks.get(endIndex);
4131            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4132                    + endIndex + " " + cur);
4133            if (cur == top) {
4134                // Verify start of the chain.
4135                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4136                    Slog.wtf(TAG, "Bad chain @" + endIndex
4137                            + ": first task has next affiliate: " + prev);
4138                    sane = false;
4139                    break;
4140                }
4141            } else {
4142                // Verify middle of the chain's next points back to the one before.
4143                if (cur.mNextAffiliate != prev
4144                        || cur.mNextAffiliateTaskId != prev.taskId) {
4145                    Slog.wtf(TAG, "Bad chain @" + endIndex
4146                            + ": middle task " + cur + " @" + endIndex
4147                            + " has bad next affiliate "
4148                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4149                            + ", expected " + prev);
4150                    sane = false;
4151                    break;
4152                }
4153            }
4154            if (cur.mPrevAffiliateTaskId == -1) {
4155                // Chain ends here.
4156                if (cur.mPrevAffiliate != null) {
4157                    Slog.wtf(TAG, "Bad chain @" + endIndex
4158                            + ": last task " + cur + " has previous affiliate "
4159                            + cur.mPrevAffiliate);
4160                    sane = false;
4161                }
4162                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4163                break;
4164            } else {
4165                // Verify middle of the chain's prev points to a valid item.
4166                if (cur.mPrevAffiliate == null) {
4167                    Slog.wtf(TAG, "Bad chain @" + endIndex
4168                            + ": task " + cur + " has previous affiliate "
4169                            + cur.mPrevAffiliate + " but should be id "
4170                            + cur.mPrevAffiliate);
4171                    sane = false;
4172                    break;
4173                }
4174            }
4175            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4176                Slog.wtf(TAG, "Bad chain @" + endIndex
4177                        + ": task " + cur + " has affiliated id "
4178                        + cur.mAffiliatedTaskId + " but should be "
4179                        + task.mAffiliatedTaskId);
4180                sane = false;
4181                break;
4182            }
4183            prev = cur;
4184            endIndex++;
4185            if (endIndex >= N) {
4186                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4187                        + ": last task " + prev);
4188                sane = false;
4189                break;
4190            }
4191        }
4192        if (sane) {
4193            if (endIndex < taskIndex) {
4194                Slog.wtf(TAG, "Bad chain @" + endIndex
4195                        + ": did not extend to task " + task + " @" + taskIndex);
4196                sane = false;
4197            }
4198        }
4199        if (sane) {
4200            // All looks good, we can just move all of the affiliated tasks
4201            // to the top.
4202            for (int i=topIndex; i<=endIndex; i++) {
4203                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4204                        + " from " + i + " to " + (i-topIndex));
4205                TaskRecord cur = mRecentTasks.remove(i);
4206                mRecentTasks.add(i-topIndex, cur);
4207            }
4208            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4209                    + " to " + endIndex);
4210            return true;
4211        }
4212
4213        // Whoops, couldn't do it.
4214        return false;
4215    }
4216
4217    final void addRecentTaskLocked(TaskRecord task) {
4218        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4219                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4220
4221        int N = mRecentTasks.size();
4222        // Quick case: check if the top-most recent task is the same.
4223        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4224            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4225            return;
4226        }
4227        // Another quick case: check if this is part of a set of affiliated
4228        // tasks that are at the top.
4229        if (isAffiliated && N > 0 && task.inRecents
4230                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4231            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4232                    + " at top when adding " + task);
4233            return;
4234        }
4235        // Another quick case: never add voice sessions.
4236        if (task.voiceSession != null) {
4237            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4238            return;
4239        }
4240
4241        boolean needAffiliationFix = false;
4242
4243        // Slightly less quick case: the task is already in recents, so all we need
4244        // to do is move it.
4245        if (task.inRecents) {
4246            int taskIndex = mRecentTasks.indexOf(task);
4247            if (taskIndex >= 0) {
4248                if (!isAffiliated) {
4249                    // Simple case: this is not an affiliated task, so we just move it to the front.
4250                    mRecentTasks.remove(taskIndex);
4251                    mRecentTasks.add(0, task);
4252                    notifyTaskPersisterLocked(task, false);
4253                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4254                            + " from " + taskIndex);
4255                    return;
4256                } else {
4257                    // More complicated: need to keep all affiliated tasks together.
4258                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4259                        // All went well.
4260                        return;
4261                    }
4262
4263                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4264                    // everything and then go through our general path of adding a new task.
4265                    needAffiliationFix = true;
4266                }
4267            } else {
4268                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4269                needAffiliationFix = true;
4270            }
4271        }
4272
4273        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4274        trimRecentsForTask(task, true);
4275
4276        N = mRecentTasks.size();
4277        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4278            final TaskRecord tr = mRecentTasks.remove(N - 1);
4279            tr.removedFromRecents(mTaskPersister);
4280            N--;
4281        }
4282        task.inRecents = true;
4283        if (!isAffiliated || needAffiliationFix) {
4284            // If this is a simple non-affiliated task, or we had some failure trying to
4285            // handle it as part of an affilated task, then just place it at the top.
4286            mRecentTasks.add(0, task);
4287        } else if (isAffiliated) {
4288            // If this is a new affiliated task, then move all of the affiliated tasks
4289            // to the front and insert this new one.
4290            TaskRecord other = task.mNextAffiliate;
4291            if (other == null) {
4292                other = task.mPrevAffiliate;
4293            }
4294            if (other != null) {
4295                int otherIndex = mRecentTasks.indexOf(other);
4296                if (otherIndex >= 0) {
4297                    // Insert new task at appropriate location.
4298                    int taskIndex;
4299                    if (other == task.mNextAffiliate) {
4300                        // We found the index of our next affiliation, which is who is
4301                        // before us in the list, so add after that point.
4302                        taskIndex = otherIndex+1;
4303                    } else {
4304                        // We found the index of our previous affiliation, which is who is
4305                        // after us in the list, so add at their position.
4306                        taskIndex = otherIndex;
4307                    }
4308                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4309                            + taskIndex + ": " + task);
4310                    mRecentTasks.add(taskIndex, task);
4311
4312                    // Now move everything to the front.
4313                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4314                        // All went well.
4315                        return;
4316                    }
4317
4318                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4319                    // everything and then go through our general path of adding a new task.
4320                    needAffiliationFix = true;
4321                } else {
4322                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4323                            + other);
4324                    needAffiliationFix = true;
4325                }
4326            } else {
4327                if (DEBUG_RECENTS) Slog.d(TAG,
4328                        "addRecent: adding affiliated task without next/prev:" + task);
4329                needAffiliationFix = true;
4330            }
4331        }
4332        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4333
4334        if (needAffiliationFix) {
4335            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4336            cleanupRecentTasksLocked(task.userId);
4337        }
4338    }
4339
4340    /**
4341     * If needed, remove oldest existing entries in recents that are for the same kind
4342     * of task as the given one.
4343     */
4344    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4345        int N = mRecentTasks.size();
4346        final Intent intent = task.intent;
4347        final boolean document = intent != null && intent.isDocument();
4348
4349        int maxRecents = task.maxRecents - 1;
4350        for (int i=0; i<N; i++) {
4351            final TaskRecord tr = mRecentTasks.get(i);
4352            if (task != tr) {
4353                if (task.userId != tr.userId) {
4354                    continue;
4355                }
4356                if (i > MAX_RECENT_BITMAPS) {
4357                    tr.freeLastThumbnail();
4358                }
4359                final Intent trIntent = tr.intent;
4360                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4361                    (intent == null || !intent.filterEquals(trIntent))) {
4362                    continue;
4363                }
4364                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4365                if (document && trIsDocument) {
4366                    // These are the same document activity (not necessarily the same doc).
4367                    if (maxRecents > 0) {
4368                        --maxRecents;
4369                        continue;
4370                    }
4371                    // Hit the maximum number of documents for this task. Fall through
4372                    // and remove this document from recents.
4373                } else if (document || trIsDocument) {
4374                    // Only one of these is a document. Not the droid we're looking for.
4375                    continue;
4376                }
4377            }
4378
4379            if (!doTrim) {
4380                // If the caller is not actually asking for a trim, just tell them we reached
4381                // a point where the trim would happen.
4382                return i;
4383            }
4384
4385            // Either task and tr are the same or, their affinities match or their intents match
4386            // and neither of them is a document, or they are documents using the same activity
4387            // and their maxRecents has been reached.
4388            tr.disposeThumbnail();
4389            mRecentTasks.remove(i);
4390            if (task != tr) {
4391                tr.removedFromRecents(mTaskPersister);
4392            }
4393            i--;
4394            N--;
4395            if (task.intent == null) {
4396                // If the new recent task we are adding is not fully
4397                // specified, then replace it with the existing recent task.
4398                task = tr;
4399            }
4400            notifyTaskPersisterLocked(tr, false);
4401        }
4402
4403        return -1;
4404    }
4405
4406    @Override
4407    public void reportActivityFullyDrawn(IBinder token) {
4408        synchronized (this) {
4409            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4410            if (r == null) {
4411                return;
4412            }
4413            r.reportFullyDrawnLocked();
4414        }
4415    }
4416
4417    @Override
4418    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4419        synchronized (this) {
4420            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4421            if (r == null) {
4422                return;
4423            }
4424            final long origId = Binder.clearCallingIdentity();
4425            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4426            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4427                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4428            if (config != null) {
4429                r.frozenBeforeDestroy = true;
4430                if (!updateConfigurationLocked(config, r, false, false)) {
4431                    mStackSupervisor.resumeTopActivitiesLocked();
4432                }
4433            }
4434            Binder.restoreCallingIdentity(origId);
4435        }
4436    }
4437
4438    @Override
4439    public int getRequestedOrientation(IBinder token) {
4440        synchronized (this) {
4441            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4442            if (r == null) {
4443                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4444            }
4445            return mWindowManager.getAppOrientation(r.appToken);
4446        }
4447    }
4448
4449    /**
4450     * This is the internal entry point for handling Activity.finish().
4451     *
4452     * @param token The Binder token referencing the Activity we want to finish.
4453     * @param resultCode Result code, if any, from this Activity.
4454     * @param resultData Result data (Intent), if any, from this Activity.
4455     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4456     *            the root Activity in the task.
4457     *
4458     * @return Returns true if the activity successfully finished, or false if it is still running.
4459     */
4460    @Override
4461    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4462            boolean finishTask) {
4463        // Refuse possible leaked file descriptors
4464        if (resultData != null && resultData.hasFileDescriptors() == true) {
4465            throw new IllegalArgumentException("File descriptors passed in Intent");
4466        }
4467
4468        synchronized(this) {
4469            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4470            if (r == null) {
4471                return true;
4472            }
4473            // Keep track of the root activity of the task before we finish it
4474            TaskRecord tr = r.task;
4475            ActivityRecord rootR = tr.getRootActivity();
4476            // Do not allow task to finish in Lock Task mode.
4477            if (tr == mStackSupervisor.mLockTaskModeTask) {
4478                if (rootR == r) {
4479                    mStackSupervisor.showLockTaskToast();
4480                    return false;
4481                }
4482            }
4483            if (mController != null) {
4484                // Find the first activity that is not finishing.
4485                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4486                if (next != null) {
4487                    // ask watcher if this is allowed
4488                    boolean resumeOK = true;
4489                    try {
4490                        resumeOK = mController.activityResuming(next.packageName);
4491                    } catch (RemoteException e) {
4492                        mController = null;
4493                        Watchdog.getInstance().setActivityController(null);
4494                    }
4495
4496                    if (!resumeOK) {
4497                        return false;
4498                    }
4499                }
4500            }
4501            final long origId = Binder.clearCallingIdentity();
4502            try {
4503                boolean res;
4504                if (finishTask && r == rootR) {
4505                    // If requested, remove the task that is associated to this activity only if it
4506                    // was the root activity in the task.  The result code and data is ignored because
4507                    // we don't support returning them across task boundaries.
4508                    res = removeTaskByIdLocked(tr.taskId, 0);
4509                } else {
4510                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4511                            resultData, "app-request", true);
4512                }
4513                return res;
4514            } finally {
4515                Binder.restoreCallingIdentity(origId);
4516            }
4517        }
4518    }
4519
4520    @Override
4521    public final void finishHeavyWeightApp() {
4522        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4523                != PackageManager.PERMISSION_GRANTED) {
4524            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4525                    + Binder.getCallingPid()
4526                    + ", uid=" + Binder.getCallingUid()
4527                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4528            Slog.w(TAG, msg);
4529            throw new SecurityException(msg);
4530        }
4531
4532        synchronized(this) {
4533            if (mHeavyWeightProcess == null) {
4534                return;
4535            }
4536
4537            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4538                    mHeavyWeightProcess.activities);
4539            for (int i=0; i<activities.size(); i++) {
4540                ActivityRecord r = activities.get(i);
4541                if (!r.finishing) {
4542                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4543                            null, "finish-heavy", true);
4544                }
4545            }
4546
4547            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4548                    mHeavyWeightProcess.userId, 0));
4549            mHeavyWeightProcess = null;
4550        }
4551    }
4552
4553    @Override
4554    public void crashApplication(int uid, int initialPid, String packageName,
4555            String message) {
4556        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4557                != PackageManager.PERMISSION_GRANTED) {
4558            String msg = "Permission Denial: crashApplication() from pid="
4559                    + Binder.getCallingPid()
4560                    + ", uid=" + Binder.getCallingUid()
4561                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4562            Slog.w(TAG, msg);
4563            throw new SecurityException(msg);
4564        }
4565
4566        synchronized(this) {
4567            ProcessRecord proc = null;
4568
4569            // Figure out which process to kill.  We don't trust that initialPid
4570            // still has any relation to current pids, so must scan through the
4571            // list.
4572            synchronized (mPidsSelfLocked) {
4573                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4574                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4575                    if (p.uid != uid) {
4576                        continue;
4577                    }
4578                    if (p.pid == initialPid) {
4579                        proc = p;
4580                        break;
4581                    }
4582                    if (p.pkgList.containsKey(packageName)) {
4583                        proc = p;
4584                    }
4585                }
4586            }
4587
4588            if (proc == null) {
4589                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4590                        + " initialPid=" + initialPid
4591                        + " packageName=" + packageName);
4592                return;
4593            }
4594
4595            if (proc.thread != null) {
4596                if (proc.pid == Process.myPid()) {
4597                    Log.w(TAG, "crashApplication: trying to crash self!");
4598                    return;
4599                }
4600                long ident = Binder.clearCallingIdentity();
4601                try {
4602                    proc.thread.scheduleCrash(message);
4603                } catch (RemoteException e) {
4604                }
4605                Binder.restoreCallingIdentity(ident);
4606            }
4607        }
4608    }
4609
4610    @Override
4611    public final void finishSubActivity(IBinder token, String resultWho,
4612            int requestCode) {
4613        synchronized(this) {
4614            final long origId = Binder.clearCallingIdentity();
4615            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4616            if (r != null) {
4617                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4618            }
4619            Binder.restoreCallingIdentity(origId);
4620        }
4621    }
4622
4623    @Override
4624    public boolean finishActivityAffinity(IBinder token) {
4625        synchronized(this) {
4626            final long origId = Binder.clearCallingIdentity();
4627            try {
4628                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4629
4630                ActivityRecord rootR = r.task.getRootActivity();
4631                // Do not allow task to finish in Lock Task mode.
4632                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4633                    if (rootR == r) {
4634                        mStackSupervisor.showLockTaskToast();
4635                        return false;
4636                    }
4637                }
4638                boolean res = false;
4639                if (r != null) {
4640                    res = r.task.stack.finishActivityAffinityLocked(r);
4641                }
4642                return res;
4643            } finally {
4644                Binder.restoreCallingIdentity(origId);
4645            }
4646        }
4647    }
4648
4649    @Override
4650    public void finishVoiceTask(IVoiceInteractionSession session) {
4651        synchronized(this) {
4652            final long origId = Binder.clearCallingIdentity();
4653            try {
4654                mStackSupervisor.finishVoiceTask(session);
4655            } finally {
4656                Binder.restoreCallingIdentity(origId);
4657            }
4658        }
4659
4660    }
4661
4662    @Override
4663    public boolean releaseActivityInstance(IBinder token) {
4664        synchronized(this) {
4665            final long origId = Binder.clearCallingIdentity();
4666            try {
4667                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4668                if (r.task == null || r.task.stack == null) {
4669                    return false;
4670                }
4671                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4672            } finally {
4673                Binder.restoreCallingIdentity(origId);
4674            }
4675        }
4676    }
4677
4678    @Override
4679    public void releaseSomeActivities(IApplicationThread appInt) {
4680        synchronized(this) {
4681            final long origId = Binder.clearCallingIdentity();
4682            try {
4683                ProcessRecord app = getRecordForAppLocked(appInt);
4684                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4685            } finally {
4686                Binder.restoreCallingIdentity(origId);
4687            }
4688        }
4689    }
4690
4691    @Override
4692    public boolean willActivityBeVisible(IBinder token) {
4693        synchronized(this) {
4694            ActivityStack stack = ActivityRecord.getStackLocked(token);
4695            if (stack != null) {
4696                return stack.willActivityBeVisibleLocked(token);
4697            }
4698            return false;
4699        }
4700    }
4701
4702    @Override
4703    public void overridePendingTransition(IBinder token, String packageName,
4704            int enterAnim, int exitAnim) {
4705        synchronized(this) {
4706            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4707            if (self == null) {
4708                return;
4709            }
4710
4711            final long origId = Binder.clearCallingIdentity();
4712
4713            if (self.state == ActivityState.RESUMED
4714                    || self.state == ActivityState.PAUSING) {
4715                mWindowManager.overridePendingAppTransition(packageName,
4716                        enterAnim, exitAnim, null);
4717            }
4718
4719            Binder.restoreCallingIdentity(origId);
4720        }
4721    }
4722
4723    /**
4724     * Main function for removing an existing process from the activity manager
4725     * as a result of that process going away.  Clears out all connections
4726     * to the process.
4727     */
4728    private final void handleAppDiedLocked(ProcessRecord app,
4729            boolean restarting, boolean allowRestart) {
4730        int pid = app.pid;
4731        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4732        if (!kept && !restarting) {
4733            removeLruProcessLocked(app);
4734            if (pid > 0) {
4735                ProcessList.remove(pid);
4736            }
4737        }
4738
4739        if (mProfileProc == app) {
4740            clearProfilerLocked();
4741        }
4742
4743        // Remove this application's activities from active lists.
4744        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4745
4746        app.activities.clear();
4747
4748        if (app.instrumentationClass != null) {
4749            Slog.w(TAG, "Crash of app " + app.processName
4750                  + " running instrumentation " + app.instrumentationClass);
4751            Bundle info = new Bundle();
4752            info.putString("shortMsg", "Process crashed.");
4753            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4754        }
4755
4756        if (!restarting) {
4757            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4758                // If there was nothing to resume, and we are not already
4759                // restarting this process, but there is a visible activity that
4760                // is hosted by the process...  then make sure all visible
4761                // activities are running, taking care of restarting this
4762                // process.
4763                if (hasVisibleActivities) {
4764                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4765                }
4766            }
4767        }
4768    }
4769
4770    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4771        IBinder threadBinder = thread.asBinder();
4772        // Find the application record.
4773        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4774            ProcessRecord rec = mLruProcesses.get(i);
4775            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4776                return i;
4777            }
4778        }
4779        return -1;
4780    }
4781
4782    final ProcessRecord getRecordForAppLocked(
4783            IApplicationThread thread) {
4784        if (thread == null) {
4785            return null;
4786        }
4787
4788        int appIndex = getLRURecordIndexForAppLocked(thread);
4789        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4790    }
4791
4792    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4793        // If there are no longer any background processes running,
4794        // and the app that died was not running instrumentation,
4795        // then tell everyone we are now low on memory.
4796        boolean haveBg = false;
4797        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4798            ProcessRecord rec = mLruProcesses.get(i);
4799            if (rec.thread != null
4800                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4801                haveBg = true;
4802                break;
4803            }
4804        }
4805
4806        if (!haveBg) {
4807            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4808            if (doReport) {
4809                long now = SystemClock.uptimeMillis();
4810                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4811                    doReport = false;
4812                } else {
4813                    mLastMemUsageReportTime = now;
4814                }
4815            }
4816            final ArrayList<ProcessMemInfo> memInfos
4817                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4818            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4819            long now = SystemClock.uptimeMillis();
4820            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4821                ProcessRecord rec = mLruProcesses.get(i);
4822                if (rec == dyingProc || rec.thread == null) {
4823                    continue;
4824                }
4825                if (doReport) {
4826                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4827                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4828                }
4829                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4830                    // The low memory report is overriding any current
4831                    // state for a GC request.  Make sure to do
4832                    // heavy/important/visible/foreground processes first.
4833                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4834                        rec.lastRequestedGc = 0;
4835                    } else {
4836                        rec.lastRequestedGc = rec.lastLowMemory;
4837                    }
4838                    rec.reportLowMemory = true;
4839                    rec.lastLowMemory = now;
4840                    mProcessesToGc.remove(rec);
4841                    addProcessToGcListLocked(rec);
4842                }
4843            }
4844            if (doReport) {
4845                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4846                mHandler.sendMessage(msg);
4847            }
4848            scheduleAppGcsLocked();
4849        }
4850    }
4851
4852    final void appDiedLocked(ProcessRecord app) {
4853       appDiedLocked(app, app.pid, app.thread);
4854    }
4855
4856    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4857        // First check if this ProcessRecord is actually active for the pid.
4858        synchronized (mPidsSelfLocked) {
4859            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4860            if (curProc != app) {
4861                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4862                return;
4863            }
4864        }
4865
4866        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4867        synchronized (stats) {
4868            stats.noteProcessDiedLocked(app.info.uid, pid);
4869        }
4870
4871        Process.killProcessQuiet(pid);
4872        Process.killProcessGroup(app.info.uid, pid);
4873        app.killed = true;
4874
4875        // Clean up already done if the process has been re-started.
4876        if (app.pid == pid && app.thread != null &&
4877                app.thread.asBinder() == thread.asBinder()) {
4878            boolean doLowMem = app.instrumentationClass == null;
4879            boolean doOomAdj = doLowMem;
4880            if (!app.killedByAm) {
4881                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4882                        + ") has died");
4883                mAllowLowerMemLevel = true;
4884            } else {
4885                // Note that we always want to do oom adj to update our state with the
4886                // new number of procs.
4887                mAllowLowerMemLevel = false;
4888                doLowMem = false;
4889            }
4890            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4891            if (DEBUG_CLEANUP) Slog.v(
4892                TAG, "Dying app: " + app + ", pid: " + pid
4893                + ", thread: " + thread.asBinder());
4894            handleAppDiedLocked(app, false, true);
4895
4896            if (doOomAdj) {
4897                updateOomAdjLocked();
4898            }
4899            if (doLowMem) {
4900                doLowMemReportIfNeededLocked(app);
4901            }
4902        } else if (app.pid != pid) {
4903            // A new process has already been started.
4904            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4905                    + ") has died and restarted (pid " + app.pid + ").");
4906            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4907        } else if (DEBUG_PROCESSES) {
4908            Slog.d(TAG, "Received spurious death notification for thread "
4909                    + thread.asBinder());
4910        }
4911    }
4912
4913    /**
4914     * If a stack trace dump file is configured, dump process stack traces.
4915     * @param clearTraces causes the dump file to be erased prior to the new
4916     *    traces being written, if true; when false, the new traces will be
4917     *    appended to any existing file content.
4918     * @param firstPids of dalvik VM processes to dump stack traces for first
4919     * @param lastPids of dalvik VM processes to dump stack traces for last
4920     * @param nativeProcs optional list of native process names to dump stack crawls
4921     * @return file containing stack traces, or null if no dump file is configured
4922     */
4923    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4924            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4925        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4926        if (tracesPath == null || tracesPath.length() == 0) {
4927            return null;
4928        }
4929
4930        File tracesFile = new File(tracesPath);
4931        try {
4932            File tracesDir = tracesFile.getParentFile();
4933            if (!tracesDir.exists()) {
4934                tracesDir.mkdirs();
4935                if (!SELinux.restorecon(tracesDir)) {
4936                    return null;
4937                }
4938            }
4939            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4940
4941            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4942            tracesFile.createNewFile();
4943            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4944        } catch (IOException e) {
4945            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4946            return null;
4947        }
4948
4949        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4950        return tracesFile;
4951    }
4952
4953    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4954            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4955        // Use a FileObserver to detect when traces finish writing.
4956        // The order of traces is considered important to maintain for legibility.
4957        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4958            @Override
4959            public synchronized void onEvent(int event, String path) { notify(); }
4960        };
4961
4962        try {
4963            observer.startWatching();
4964
4965            // First collect all of the stacks of the most important pids.
4966            if (firstPids != null) {
4967                try {
4968                    int num = firstPids.size();
4969                    for (int i = 0; i < num; i++) {
4970                        synchronized (observer) {
4971                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4972                            observer.wait(200);  // Wait for write-close, give up after 200msec
4973                        }
4974                    }
4975                } catch (InterruptedException e) {
4976                    Slog.wtf(TAG, e);
4977                }
4978            }
4979
4980            // Next collect the stacks of the native pids
4981            if (nativeProcs != null) {
4982                int[] pids = Process.getPidsForCommands(nativeProcs);
4983                if (pids != null) {
4984                    for (int pid : pids) {
4985                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4986                    }
4987                }
4988            }
4989
4990            // Lastly, measure CPU usage.
4991            if (processCpuTracker != null) {
4992                processCpuTracker.init();
4993                System.gc();
4994                processCpuTracker.update();
4995                try {
4996                    synchronized (processCpuTracker) {
4997                        processCpuTracker.wait(500); // measure over 1/2 second.
4998                    }
4999                } catch (InterruptedException e) {
5000                }
5001                processCpuTracker.update();
5002
5003                // We'll take the stack crawls of just the top apps using CPU.
5004                final int N = processCpuTracker.countWorkingStats();
5005                int numProcs = 0;
5006                for (int i=0; i<N && numProcs<5; i++) {
5007                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5008                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5009                        numProcs++;
5010                        try {
5011                            synchronized (observer) {
5012                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5013                                observer.wait(200);  // Wait for write-close, give up after 200msec
5014                            }
5015                        } catch (InterruptedException e) {
5016                            Slog.wtf(TAG, e);
5017                        }
5018
5019                    }
5020                }
5021            }
5022        } finally {
5023            observer.stopWatching();
5024        }
5025    }
5026
5027    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5028        if (true || IS_USER_BUILD) {
5029            return;
5030        }
5031        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5032        if (tracesPath == null || tracesPath.length() == 0) {
5033            return;
5034        }
5035
5036        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5037        StrictMode.allowThreadDiskWrites();
5038        try {
5039            final File tracesFile = new File(tracesPath);
5040            final File tracesDir = tracesFile.getParentFile();
5041            final File tracesTmp = new File(tracesDir, "__tmp__");
5042            try {
5043                if (!tracesDir.exists()) {
5044                    tracesDir.mkdirs();
5045                    if (!SELinux.restorecon(tracesDir.getPath())) {
5046                        return;
5047                    }
5048                }
5049                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5050
5051                if (tracesFile.exists()) {
5052                    tracesTmp.delete();
5053                    tracesFile.renameTo(tracesTmp);
5054                }
5055                StringBuilder sb = new StringBuilder();
5056                Time tobj = new Time();
5057                tobj.set(System.currentTimeMillis());
5058                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5059                sb.append(": ");
5060                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5061                sb.append(" since ");
5062                sb.append(msg);
5063                FileOutputStream fos = new FileOutputStream(tracesFile);
5064                fos.write(sb.toString().getBytes());
5065                if (app == null) {
5066                    fos.write("\n*** No application process!".getBytes());
5067                }
5068                fos.close();
5069                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5070            } catch (IOException e) {
5071                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5072                return;
5073            }
5074
5075            if (app != null) {
5076                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5077                firstPids.add(app.pid);
5078                dumpStackTraces(tracesPath, firstPids, null, null, null);
5079            }
5080
5081            File lastTracesFile = null;
5082            File curTracesFile = null;
5083            for (int i=9; i>=0; i--) {
5084                String name = String.format(Locale.US, "slow%02d.txt", i);
5085                curTracesFile = new File(tracesDir, name);
5086                if (curTracesFile.exists()) {
5087                    if (lastTracesFile != null) {
5088                        curTracesFile.renameTo(lastTracesFile);
5089                    } else {
5090                        curTracesFile.delete();
5091                    }
5092                }
5093                lastTracesFile = curTracesFile;
5094            }
5095            tracesFile.renameTo(curTracesFile);
5096            if (tracesTmp.exists()) {
5097                tracesTmp.renameTo(tracesFile);
5098            }
5099        } finally {
5100            StrictMode.setThreadPolicy(oldPolicy);
5101        }
5102    }
5103
5104    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5105            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5106        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5107        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5108
5109        if (mController != null) {
5110            try {
5111                // 0 == continue, -1 = kill process immediately
5112                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5113                if (res < 0 && app.pid != MY_PID) {
5114                    app.kill("anr", true);
5115                }
5116            } catch (RemoteException e) {
5117                mController = null;
5118                Watchdog.getInstance().setActivityController(null);
5119            }
5120        }
5121
5122        long anrTime = SystemClock.uptimeMillis();
5123        if (MONITOR_CPU_USAGE) {
5124            updateCpuStatsNow();
5125        }
5126
5127        synchronized (this) {
5128            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5129            if (mShuttingDown) {
5130                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5131                return;
5132            } else if (app.notResponding) {
5133                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5134                return;
5135            } else if (app.crashing) {
5136                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5137                return;
5138            }
5139
5140            // In case we come through here for the same app before completing
5141            // this one, mark as anring now so we will bail out.
5142            app.notResponding = true;
5143
5144            // Log the ANR to the event log.
5145            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5146                    app.processName, app.info.flags, annotation);
5147
5148            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5149            firstPids.add(app.pid);
5150
5151            int parentPid = app.pid;
5152            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5153            if (parentPid != app.pid) firstPids.add(parentPid);
5154
5155            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5156
5157            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5158                ProcessRecord r = mLruProcesses.get(i);
5159                if (r != null && r.thread != null) {
5160                    int pid = r.pid;
5161                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5162                        if (r.persistent) {
5163                            firstPids.add(pid);
5164                        } else {
5165                            lastPids.put(pid, Boolean.TRUE);
5166                        }
5167                    }
5168                }
5169            }
5170        }
5171
5172        // Log the ANR to the main log.
5173        StringBuilder info = new StringBuilder();
5174        info.setLength(0);
5175        info.append("ANR in ").append(app.processName);
5176        if (activity != null && activity.shortComponentName != null) {
5177            info.append(" (").append(activity.shortComponentName).append(")");
5178        }
5179        info.append("\n");
5180        info.append("PID: ").append(app.pid).append("\n");
5181        if (annotation != null) {
5182            info.append("Reason: ").append(annotation).append("\n");
5183        }
5184        if (parent != null && parent != activity) {
5185            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5186        }
5187
5188        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5189
5190        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5191                NATIVE_STACKS_OF_INTEREST);
5192
5193        String cpuInfo = null;
5194        if (MONITOR_CPU_USAGE) {
5195            updateCpuStatsNow();
5196            synchronized (mProcessCpuTracker) {
5197                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5198            }
5199            info.append(processCpuTracker.printCurrentLoad());
5200            info.append(cpuInfo);
5201        }
5202
5203        info.append(processCpuTracker.printCurrentState(anrTime));
5204
5205        Slog.e(TAG, info.toString());
5206        if (tracesFile == null) {
5207            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5208            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5209        }
5210
5211        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5212                cpuInfo, tracesFile, null);
5213
5214        if (mController != null) {
5215            try {
5216                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5217                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5218                if (res != 0) {
5219                    if (res < 0 && app.pid != MY_PID) {
5220                        app.kill("anr", true);
5221                    } else {
5222                        synchronized (this) {
5223                            mServices.scheduleServiceTimeoutLocked(app);
5224                        }
5225                    }
5226                    return;
5227                }
5228            } catch (RemoteException e) {
5229                mController = null;
5230                Watchdog.getInstance().setActivityController(null);
5231            }
5232        }
5233
5234        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5235        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5236                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5237
5238        synchronized (this) {
5239            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5240                app.kill("bg anr", true);
5241                return;
5242            }
5243
5244            // Set the app's notResponding state, and look up the errorReportReceiver
5245            makeAppNotRespondingLocked(app,
5246                    activity != null ? activity.shortComponentName : null,
5247                    annotation != null ? "ANR " + annotation : "ANR",
5248                    info.toString());
5249
5250            // Bring up the infamous App Not Responding dialog
5251            Message msg = Message.obtain();
5252            HashMap<String, Object> map = new HashMap<String, Object>();
5253            msg.what = SHOW_NOT_RESPONDING_MSG;
5254            msg.obj = map;
5255            msg.arg1 = aboveSystem ? 1 : 0;
5256            map.put("app", app);
5257            if (activity != null) {
5258                map.put("activity", activity);
5259            }
5260
5261            mHandler.sendMessage(msg);
5262        }
5263    }
5264
5265    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5266        if (!mLaunchWarningShown) {
5267            mLaunchWarningShown = true;
5268            mHandler.post(new Runnable() {
5269                @Override
5270                public void run() {
5271                    synchronized (ActivityManagerService.this) {
5272                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5273                        d.show();
5274                        mHandler.postDelayed(new Runnable() {
5275                            @Override
5276                            public void run() {
5277                                synchronized (ActivityManagerService.this) {
5278                                    d.dismiss();
5279                                    mLaunchWarningShown = false;
5280                                }
5281                            }
5282                        }, 4000);
5283                    }
5284                }
5285            });
5286        }
5287    }
5288
5289    @Override
5290    public boolean clearApplicationUserData(final String packageName,
5291            final IPackageDataObserver observer, int userId) {
5292        enforceNotIsolatedCaller("clearApplicationUserData");
5293        int uid = Binder.getCallingUid();
5294        int pid = Binder.getCallingPid();
5295        userId = handleIncomingUser(pid, uid,
5296                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5297        long callingId = Binder.clearCallingIdentity();
5298        try {
5299            IPackageManager pm = AppGlobals.getPackageManager();
5300            int pkgUid = -1;
5301            synchronized(this) {
5302                try {
5303                    pkgUid = pm.getPackageUid(packageName, userId);
5304                } catch (RemoteException e) {
5305                }
5306                if (pkgUid == -1) {
5307                    Slog.w(TAG, "Invalid packageName: " + packageName);
5308                    if (observer != null) {
5309                        try {
5310                            observer.onRemoveCompleted(packageName, false);
5311                        } catch (RemoteException e) {
5312                            Slog.i(TAG, "Observer no longer exists.");
5313                        }
5314                    }
5315                    return false;
5316                }
5317                if (uid == pkgUid || checkComponentPermission(
5318                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5319                        pid, uid, -1, true)
5320                        == PackageManager.PERMISSION_GRANTED) {
5321                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5322                } else {
5323                    throw new SecurityException("PID " + pid + " does not have permission "
5324                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5325                                    + " of package " + packageName);
5326                }
5327
5328                // Remove all tasks match the cleared application package and user
5329                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5330                    final TaskRecord tr = mRecentTasks.get(i);
5331                    final String taskPackageName =
5332                            tr.getBaseIntent().getComponent().getPackageName();
5333                    if (tr.userId != userId) continue;
5334                    if (!taskPackageName.equals(packageName)) continue;
5335                    removeTaskByIdLocked(tr.taskId, 0);
5336                }
5337            }
5338
5339            try {
5340                // Clear application user data
5341                pm.clearApplicationUserData(packageName, observer, userId);
5342
5343                synchronized(this) {
5344                    // Remove all permissions granted from/to this package
5345                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5346                }
5347
5348                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5349                        Uri.fromParts("package", packageName, null));
5350                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5351                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5352                        null, null, 0, null, null, null, false, false, userId);
5353            } catch (RemoteException e) {
5354            }
5355        } finally {
5356            Binder.restoreCallingIdentity(callingId);
5357        }
5358        return true;
5359    }
5360
5361    @Override
5362    public void killBackgroundProcesses(final String packageName, int userId) {
5363        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5364                != PackageManager.PERMISSION_GRANTED &&
5365                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5366                        != PackageManager.PERMISSION_GRANTED) {
5367            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5368                    + Binder.getCallingPid()
5369                    + ", uid=" + Binder.getCallingUid()
5370                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5371            Slog.w(TAG, msg);
5372            throw new SecurityException(msg);
5373        }
5374
5375        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5376                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5377        long callingId = Binder.clearCallingIdentity();
5378        try {
5379            IPackageManager pm = AppGlobals.getPackageManager();
5380            synchronized(this) {
5381                int appId = -1;
5382                try {
5383                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5384                } catch (RemoteException e) {
5385                }
5386                if (appId == -1) {
5387                    Slog.w(TAG, "Invalid packageName: " + packageName);
5388                    return;
5389                }
5390                killPackageProcessesLocked(packageName, appId, userId,
5391                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5392            }
5393        } finally {
5394            Binder.restoreCallingIdentity(callingId);
5395        }
5396    }
5397
5398    @Override
5399    public void killAllBackgroundProcesses() {
5400        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5401                != PackageManager.PERMISSION_GRANTED) {
5402            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5403                    + Binder.getCallingPid()
5404                    + ", uid=" + Binder.getCallingUid()
5405                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5406            Slog.w(TAG, msg);
5407            throw new SecurityException(msg);
5408        }
5409
5410        long callingId = Binder.clearCallingIdentity();
5411        try {
5412            synchronized(this) {
5413                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5414                final int NP = mProcessNames.getMap().size();
5415                for (int ip=0; ip<NP; ip++) {
5416                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5417                    final int NA = apps.size();
5418                    for (int ia=0; ia<NA; ia++) {
5419                        ProcessRecord app = apps.valueAt(ia);
5420                        if (app.persistent) {
5421                            // we don't kill persistent processes
5422                            continue;
5423                        }
5424                        if (app.removed) {
5425                            procs.add(app);
5426                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5427                            app.removed = true;
5428                            procs.add(app);
5429                        }
5430                    }
5431                }
5432
5433                int N = procs.size();
5434                for (int i=0; i<N; i++) {
5435                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5436                }
5437                mAllowLowerMemLevel = true;
5438                updateOomAdjLocked();
5439                doLowMemReportIfNeededLocked(null);
5440            }
5441        } finally {
5442            Binder.restoreCallingIdentity(callingId);
5443        }
5444    }
5445
5446    @Override
5447    public void forceStopPackage(final String packageName, int userId) {
5448        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5449                != PackageManager.PERMISSION_GRANTED) {
5450            String msg = "Permission Denial: forceStopPackage() from pid="
5451                    + Binder.getCallingPid()
5452                    + ", uid=" + Binder.getCallingUid()
5453                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5454            Slog.w(TAG, msg);
5455            throw new SecurityException(msg);
5456        }
5457        final int callingPid = Binder.getCallingPid();
5458        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5459                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5460        long callingId = Binder.clearCallingIdentity();
5461        try {
5462            IPackageManager pm = AppGlobals.getPackageManager();
5463            synchronized(this) {
5464                int[] users = userId == UserHandle.USER_ALL
5465                        ? getUsersLocked() : new int[] { userId };
5466                for (int user : users) {
5467                    int pkgUid = -1;
5468                    try {
5469                        pkgUid = pm.getPackageUid(packageName, user);
5470                    } catch (RemoteException e) {
5471                    }
5472                    if (pkgUid == -1) {
5473                        Slog.w(TAG, "Invalid packageName: " + packageName);
5474                        continue;
5475                    }
5476                    try {
5477                        pm.setPackageStoppedState(packageName, true, user);
5478                    } catch (RemoteException e) {
5479                    } catch (IllegalArgumentException e) {
5480                        Slog.w(TAG, "Failed trying to unstop package "
5481                                + packageName + ": " + e);
5482                    }
5483                    if (isUserRunningLocked(user, false)) {
5484                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5485                    }
5486                }
5487            }
5488        } finally {
5489            Binder.restoreCallingIdentity(callingId);
5490        }
5491    }
5492
5493    @Override
5494    public void addPackageDependency(String packageName) {
5495        synchronized (this) {
5496            int callingPid = Binder.getCallingPid();
5497            if (callingPid == Process.myPid()) {
5498                //  Yeah, um, no.
5499                Slog.w(TAG, "Can't addPackageDependency on system process");
5500                return;
5501            }
5502            ProcessRecord proc;
5503            synchronized (mPidsSelfLocked) {
5504                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5505            }
5506            if (proc != null) {
5507                if (proc.pkgDeps == null) {
5508                    proc.pkgDeps = new ArraySet<String>(1);
5509                }
5510                proc.pkgDeps.add(packageName);
5511            }
5512        }
5513    }
5514
5515    /*
5516     * The pkg name and app id have to be specified.
5517     */
5518    @Override
5519    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5520        if (pkg == null) {
5521            return;
5522        }
5523        // Make sure the uid is valid.
5524        if (appid < 0) {
5525            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5526            return;
5527        }
5528        int callerUid = Binder.getCallingUid();
5529        // Only the system server can kill an application
5530        if (callerUid == Process.SYSTEM_UID) {
5531            // Post an aysnc message to kill the application
5532            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5533            msg.arg1 = appid;
5534            msg.arg2 = 0;
5535            Bundle bundle = new Bundle();
5536            bundle.putString("pkg", pkg);
5537            bundle.putString("reason", reason);
5538            msg.obj = bundle;
5539            mHandler.sendMessage(msg);
5540        } else {
5541            throw new SecurityException(callerUid + " cannot kill pkg: " +
5542                    pkg);
5543        }
5544    }
5545
5546    @Override
5547    public void closeSystemDialogs(String reason) {
5548        enforceNotIsolatedCaller("closeSystemDialogs");
5549
5550        final int pid = Binder.getCallingPid();
5551        final int uid = Binder.getCallingUid();
5552        final long origId = Binder.clearCallingIdentity();
5553        try {
5554            synchronized (this) {
5555                // Only allow this from foreground processes, so that background
5556                // applications can't abuse it to prevent system UI from being shown.
5557                if (uid >= Process.FIRST_APPLICATION_UID) {
5558                    ProcessRecord proc;
5559                    synchronized (mPidsSelfLocked) {
5560                        proc = mPidsSelfLocked.get(pid);
5561                    }
5562                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5563                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5564                                + " from background process " + proc);
5565                        return;
5566                    }
5567                }
5568                closeSystemDialogsLocked(reason);
5569            }
5570        } finally {
5571            Binder.restoreCallingIdentity(origId);
5572        }
5573    }
5574
5575    void closeSystemDialogsLocked(String reason) {
5576        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5577        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5578                | Intent.FLAG_RECEIVER_FOREGROUND);
5579        if (reason != null) {
5580            intent.putExtra("reason", reason);
5581        }
5582        mWindowManager.closeSystemDialogs(reason);
5583
5584        mStackSupervisor.closeSystemDialogsLocked();
5585
5586        broadcastIntentLocked(null, null, intent, null,
5587                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5588                Process.SYSTEM_UID, UserHandle.USER_ALL);
5589    }
5590
5591    @Override
5592    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5593        enforceNotIsolatedCaller("getProcessMemoryInfo");
5594        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5595        for (int i=pids.length-1; i>=0; i--) {
5596            ProcessRecord proc;
5597            int oomAdj;
5598            synchronized (this) {
5599                synchronized (mPidsSelfLocked) {
5600                    proc = mPidsSelfLocked.get(pids[i]);
5601                    oomAdj = proc != null ? proc.setAdj : 0;
5602                }
5603            }
5604            infos[i] = new Debug.MemoryInfo();
5605            Debug.getMemoryInfo(pids[i], infos[i]);
5606            if (proc != null) {
5607                synchronized (this) {
5608                    if (proc.thread != null && proc.setAdj == oomAdj) {
5609                        // Record this for posterity if the process has been stable.
5610                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5611                                infos[i].getTotalUss(), false, proc.pkgList);
5612                    }
5613                }
5614            }
5615        }
5616        return infos;
5617    }
5618
5619    @Override
5620    public long[] getProcessPss(int[] pids) {
5621        enforceNotIsolatedCaller("getProcessPss");
5622        long[] pss = new long[pids.length];
5623        for (int i=pids.length-1; i>=0; i--) {
5624            ProcessRecord proc;
5625            int oomAdj;
5626            synchronized (this) {
5627                synchronized (mPidsSelfLocked) {
5628                    proc = mPidsSelfLocked.get(pids[i]);
5629                    oomAdj = proc != null ? proc.setAdj : 0;
5630                }
5631            }
5632            long[] tmpUss = new long[1];
5633            pss[i] = Debug.getPss(pids[i], tmpUss);
5634            if (proc != null) {
5635                synchronized (this) {
5636                    if (proc.thread != null && proc.setAdj == oomAdj) {
5637                        // Record this for posterity if the process has been stable.
5638                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5639                    }
5640                }
5641            }
5642        }
5643        return pss;
5644    }
5645
5646    @Override
5647    public void killApplicationProcess(String processName, int uid) {
5648        if (processName == null) {
5649            return;
5650        }
5651
5652        int callerUid = Binder.getCallingUid();
5653        // Only the system server can kill an application
5654        if (callerUid == Process.SYSTEM_UID) {
5655            synchronized (this) {
5656                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5657                if (app != null && app.thread != null) {
5658                    try {
5659                        app.thread.scheduleSuicide();
5660                    } catch (RemoteException e) {
5661                        // If the other end already died, then our work here is done.
5662                    }
5663                } else {
5664                    Slog.w(TAG, "Process/uid not found attempting kill of "
5665                            + processName + " / " + uid);
5666                }
5667            }
5668        } else {
5669            throw new SecurityException(callerUid + " cannot kill app process: " +
5670                    processName);
5671        }
5672    }
5673
5674    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5675        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5676                false, true, false, false, UserHandle.getUserId(uid), reason);
5677        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5678                Uri.fromParts("package", packageName, null));
5679        if (!mProcessesReady) {
5680            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5681                    | Intent.FLAG_RECEIVER_FOREGROUND);
5682        }
5683        intent.putExtra(Intent.EXTRA_UID, uid);
5684        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5685        broadcastIntentLocked(null, null, intent,
5686                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5687                false, false,
5688                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5689    }
5690
5691    private void forceStopUserLocked(int userId, String reason) {
5692        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5693        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5694        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5695                | Intent.FLAG_RECEIVER_FOREGROUND);
5696        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5697        broadcastIntentLocked(null, null, intent,
5698                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5699                false, false,
5700                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5701    }
5702
5703    private final boolean killPackageProcessesLocked(String packageName, int appId,
5704            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5705            boolean doit, boolean evenPersistent, String reason) {
5706        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5707
5708        // Remove all processes this package may have touched: all with the
5709        // same UID (except for the system or root user), and all whose name
5710        // matches the package name.
5711        final int NP = mProcessNames.getMap().size();
5712        for (int ip=0; ip<NP; ip++) {
5713            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5714            final int NA = apps.size();
5715            for (int ia=0; ia<NA; ia++) {
5716                ProcessRecord app = apps.valueAt(ia);
5717                if (app.persistent && !evenPersistent) {
5718                    // we don't kill persistent processes
5719                    continue;
5720                }
5721                if (app.removed) {
5722                    if (doit) {
5723                        procs.add(app);
5724                    }
5725                    continue;
5726                }
5727
5728                // Skip process if it doesn't meet our oom adj requirement.
5729                if (app.setAdj < minOomAdj) {
5730                    continue;
5731                }
5732
5733                // If no package is specified, we call all processes under the
5734                // give user id.
5735                if (packageName == null) {
5736                    if (app.userId != userId) {
5737                        continue;
5738                    }
5739                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5740                        continue;
5741                    }
5742                // Package has been specified, we want to hit all processes
5743                // that match it.  We need to qualify this by the processes
5744                // that are running under the specified app and user ID.
5745                } else {
5746                    final boolean isDep = app.pkgDeps != null
5747                            && app.pkgDeps.contains(packageName);
5748                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5749                        continue;
5750                    }
5751                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5752                        continue;
5753                    }
5754                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5755                        continue;
5756                    }
5757                }
5758
5759                // Process has passed all conditions, kill it!
5760                if (!doit) {
5761                    return true;
5762                }
5763                app.removed = true;
5764                procs.add(app);
5765            }
5766        }
5767
5768        int N = procs.size();
5769        for (int i=0; i<N; i++) {
5770            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5771        }
5772        updateOomAdjLocked();
5773        return N > 0;
5774    }
5775
5776    private final boolean forceStopPackageLocked(String name, int appId,
5777            boolean callerWillRestart, boolean purgeCache, boolean doit,
5778            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5779        int i;
5780        int N;
5781
5782        if (userId == UserHandle.USER_ALL && name == null) {
5783            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5784        }
5785
5786        if (appId < 0 && name != null) {
5787            try {
5788                appId = UserHandle.getAppId(
5789                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5790            } catch (RemoteException e) {
5791            }
5792        }
5793
5794        if (doit) {
5795            if (name != null) {
5796                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5797                        + " user=" + userId + ": " + reason);
5798            } else {
5799                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5800            }
5801
5802            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5803            for (int ip=pmap.size()-1; ip>=0; ip--) {
5804                SparseArray<Long> ba = pmap.valueAt(ip);
5805                for (i=ba.size()-1; i>=0; i--) {
5806                    boolean remove = false;
5807                    final int entUid = ba.keyAt(i);
5808                    if (name != null) {
5809                        if (userId == UserHandle.USER_ALL) {
5810                            if (UserHandle.getAppId(entUid) == appId) {
5811                                remove = true;
5812                            }
5813                        } else {
5814                            if (entUid == UserHandle.getUid(userId, appId)) {
5815                                remove = true;
5816                            }
5817                        }
5818                    } else if (UserHandle.getUserId(entUid) == userId) {
5819                        remove = true;
5820                    }
5821                    if (remove) {
5822                        ba.removeAt(i);
5823                    }
5824                }
5825                if (ba.size() == 0) {
5826                    pmap.removeAt(ip);
5827                }
5828            }
5829        }
5830
5831        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5832                -100, callerWillRestart, true, doit, evenPersistent,
5833                name == null ? ("stop user " + userId) : ("stop " + name));
5834
5835        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5836            if (!doit) {
5837                return true;
5838            }
5839            didSomething = true;
5840        }
5841
5842        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5843            if (!doit) {
5844                return true;
5845            }
5846            didSomething = true;
5847        }
5848
5849        if (name == null) {
5850            // Remove all sticky broadcasts from this user.
5851            mStickyBroadcasts.remove(userId);
5852        }
5853
5854        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5855        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5856                userId, providers)) {
5857            if (!doit) {
5858                return true;
5859            }
5860            didSomething = true;
5861        }
5862        N = providers.size();
5863        for (i=0; i<N; i++) {
5864            removeDyingProviderLocked(null, providers.get(i), true);
5865        }
5866
5867        // Remove transient permissions granted from/to this package/user
5868        removeUriPermissionsForPackageLocked(name, userId, false);
5869
5870        if (name == null || uninstalling) {
5871            // Remove pending intents.  For now we only do this when force
5872            // stopping users, because we have some problems when doing this
5873            // for packages -- app widgets are not currently cleaned up for
5874            // such packages, so they can be left with bad pending intents.
5875            if (mIntentSenderRecords.size() > 0) {
5876                Iterator<WeakReference<PendingIntentRecord>> it
5877                        = mIntentSenderRecords.values().iterator();
5878                while (it.hasNext()) {
5879                    WeakReference<PendingIntentRecord> wpir = it.next();
5880                    if (wpir == null) {
5881                        it.remove();
5882                        continue;
5883                    }
5884                    PendingIntentRecord pir = wpir.get();
5885                    if (pir == null) {
5886                        it.remove();
5887                        continue;
5888                    }
5889                    if (name == null) {
5890                        // Stopping user, remove all objects for the user.
5891                        if (pir.key.userId != userId) {
5892                            // Not the same user, skip it.
5893                            continue;
5894                        }
5895                    } else {
5896                        if (UserHandle.getAppId(pir.uid) != appId) {
5897                            // Different app id, skip it.
5898                            continue;
5899                        }
5900                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5901                            // Different user, skip it.
5902                            continue;
5903                        }
5904                        if (!pir.key.packageName.equals(name)) {
5905                            // Different package, skip it.
5906                            continue;
5907                        }
5908                    }
5909                    if (!doit) {
5910                        return true;
5911                    }
5912                    didSomething = true;
5913                    it.remove();
5914                    pir.canceled = true;
5915                    if (pir.key.activity != null) {
5916                        pir.key.activity.pendingResults.remove(pir.ref);
5917                    }
5918                }
5919            }
5920        }
5921
5922        if (doit) {
5923            if (purgeCache && name != null) {
5924                AttributeCache ac = AttributeCache.instance();
5925                if (ac != null) {
5926                    ac.removePackage(name);
5927                }
5928            }
5929            if (mBooted) {
5930                mStackSupervisor.resumeTopActivitiesLocked();
5931                mStackSupervisor.scheduleIdleLocked();
5932            }
5933        }
5934
5935        return didSomething;
5936    }
5937
5938    private final boolean removeProcessLocked(ProcessRecord app,
5939            boolean callerWillRestart, boolean allowRestart, String reason) {
5940        final String name = app.processName;
5941        final int uid = app.uid;
5942        if (DEBUG_PROCESSES) Slog.d(
5943            TAG, "Force removing proc " + app.toShortString() + " (" + name
5944            + "/" + uid + ")");
5945
5946        mProcessNames.remove(name, uid);
5947        mIsolatedProcesses.remove(app.uid);
5948        if (mHeavyWeightProcess == app) {
5949            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5950                    mHeavyWeightProcess.userId, 0));
5951            mHeavyWeightProcess = null;
5952        }
5953        boolean needRestart = false;
5954        if (app.pid > 0 && app.pid != MY_PID) {
5955            int pid = app.pid;
5956            synchronized (mPidsSelfLocked) {
5957                mPidsSelfLocked.remove(pid);
5958                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5959            }
5960            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5961            if (app.isolated) {
5962                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5963            }
5964            app.kill(reason, true);
5965            handleAppDiedLocked(app, true, allowRestart);
5966            removeLruProcessLocked(app);
5967
5968            if (app.persistent && !app.isolated) {
5969                if (!callerWillRestart) {
5970                    addAppLocked(app.info, false, null /* ABI override */);
5971                } else {
5972                    needRestart = true;
5973                }
5974            }
5975        } else {
5976            mRemovedProcesses.add(app);
5977        }
5978
5979        return needRestart;
5980    }
5981
5982    private final void processStartTimedOutLocked(ProcessRecord app) {
5983        final int pid = app.pid;
5984        boolean gone = false;
5985        synchronized (mPidsSelfLocked) {
5986            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5987            if (knownApp != null && knownApp.thread == null) {
5988                mPidsSelfLocked.remove(pid);
5989                gone = true;
5990            }
5991        }
5992
5993        if (gone) {
5994            Slog.w(TAG, "Process " + app + " failed to attach");
5995            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5996                    pid, app.uid, app.processName);
5997            mProcessNames.remove(app.processName, app.uid);
5998            mIsolatedProcesses.remove(app.uid);
5999            if (mHeavyWeightProcess == app) {
6000                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6001                        mHeavyWeightProcess.userId, 0));
6002                mHeavyWeightProcess = null;
6003            }
6004            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6005            if (app.isolated) {
6006                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6007            }
6008            // Take care of any launching providers waiting for this process.
6009            checkAppInLaunchingProvidersLocked(app, true);
6010            // Take care of any services that are waiting for the process.
6011            mServices.processStartTimedOutLocked(app);
6012            app.kill("start timeout", true);
6013            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6014                Slog.w(TAG, "Unattached app died before backup, skipping");
6015                try {
6016                    IBackupManager bm = IBackupManager.Stub.asInterface(
6017                            ServiceManager.getService(Context.BACKUP_SERVICE));
6018                    bm.agentDisconnected(app.info.packageName);
6019                } catch (RemoteException e) {
6020                    // Can't happen; the backup manager is local
6021                }
6022            }
6023            if (isPendingBroadcastProcessLocked(pid)) {
6024                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6025                skipPendingBroadcastLocked(pid);
6026            }
6027        } else {
6028            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6029        }
6030    }
6031
6032    private final boolean attachApplicationLocked(IApplicationThread thread,
6033            int pid) {
6034
6035        // Find the application record that is being attached...  either via
6036        // the pid if we are running in multiple processes, or just pull the
6037        // next app record if we are emulating process with anonymous threads.
6038        ProcessRecord app;
6039        if (pid != MY_PID && pid >= 0) {
6040            synchronized (mPidsSelfLocked) {
6041                app = mPidsSelfLocked.get(pid);
6042            }
6043        } else {
6044            app = null;
6045        }
6046
6047        if (app == null) {
6048            Slog.w(TAG, "No pending application record for pid " + pid
6049                    + " (IApplicationThread " + thread + "); dropping process");
6050            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6051            if (pid > 0 && pid != MY_PID) {
6052                Process.killProcessQuiet(pid);
6053                //TODO: Process.killProcessGroup(app.info.uid, pid);
6054            } else {
6055                try {
6056                    thread.scheduleExit();
6057                } catch (Exception e) {
6058                    // Ignore exceptions.
6059                }
6060            }
6061            return false;
6062        }
6063
6064        // If this application record is still attached to a previous
6065        // process, clean it up now.
6066        if (app.thread != null) {
6067            handleAppDiedLocked(app, true, true);
6068        }
6069
6070        // Tell the process all about itself.
6071
6072        if (localLOGV) Slog.v(
6073                TAG, "Binding process pid " + pid + " to record " + app);
6074
6075        final String processName = app.processName;
6076        try {
6077            AppDeathRecipient adr = new AppDeathRecipient(
6078                    app, pid, thread);
6079            thread.asBinder().linkToDeath(adr, 0);
6080            app.deathRecipient = adr;
6081        } catch (RemoteException e) {
6082            app.resetPackageList(mProcessStats);
6083            startProcessLocked(app, "link fail", processName);
6084            return false;
6085        }
6086
6087        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6088
6089        app.makeActive(thread, mProcessStats);
6090        app.curAdj = app.setAdj = -100;
6091        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6092        app.forcingToForeground = null;
6093        updateProcessForegroundLocked(app, false, false);
6094        app.hasShownUi = false;
6095        app.debugging = false;
6096        app.cached = false;
6097
6098        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6099
6100        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6101        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6102
6103        if (!normalMode) {
6104            Slog.i(TAG, "Launching preboot mode app: " + app);
6105        }
6106
6107        if (localLOGV) Slog.v(
6108            TAG, "New app record " + app
6109            + " thread=" + thread.asBinder() + " pid=" + pid);
6110        try {
6111            int testMode = IApplicationThread.DEBUG_OFF;
6112            if (mDebugApp != null && mDebugApp.equals(processName)) {
6113                testMode = mWaitForDebugger
6114                    ? IApplicationThread.DEBUG_WAIT
6115                    : IApplicationThread.DEBUG_ON;
6116                app.debugging = true;
6117                if (mDebugTransient) {
6118                    mDebugApp = mOrigDebugApp;
6119                    mWaitForDebugger = mOrigWaitForDebugger;
6120                }
6121            }
6122            String profileFile = app.instrumentationProfileFile;
6123            ParcelFileDescriptor profileFd = null;
6124            int samplingInterval = 0;
6125            boolean profileAutoStop = false;
6126            if (mProfileApp != null && mProfileApp.equals(processName)) {
6127                mProfileProc = app;
6128                profileFile = mProfileFile;
6129                profileFd = mProfileFd;
6130                samplingInterval = mSamplingInterval;
6131                profileAutoStop = mAutoStopProfiler;
6132            }
6133            boolean enableOpenGlTrace = false;
6134            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6135                enableOpenGlTrace = true;
6136                mOpenGlTraceApp = null;
6137            }
6138
6139            // If the app is being launched for restore or full backup, set it up specially
6140            boolean isRestrictedBackupMode = false;
6141            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6142                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6143                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6144                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6145            }
6146
6147            ensurePackageDexOpt(app.instrumentationInfo != null
6148                    ? app.instrumentationInfo.packageName
6149                    : app.info.packageName);
6150            if (app.instrumentationClass != null) {
6151                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6152            }
6153            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6154                    + processName + " with config " + mConfiguration);
6155            ApplicationInfo appInfo = app.instrumentationInfo != null
6156                    ? app.instrumentationInfo : app.info;
6157            app.compat = compatibilityInfoForPackageLocked(appInfo);
6158            if (profileFd != null) {
6159                profileFd = profileFd.dup();
6160            }
6161            ProfilerInfo profilerInfo = profileFile == null ? null
6162                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6163            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6164                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6165                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6166                    isRestrictedBackupMode || !normalMode, app.persistent,
6167                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6168                    mCoreSettingsObserver.getCoreSettingsLocked());
6169            updateLruProcessLocked(app, false, null);
6170            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6171        } catch (Exception e) {
6172            // todo: Yikes!  What should we do?  For now we will try to
6173            // start another process, but that could easily get us in
6174            // an infinite loop of restarting processes...
6175            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6176
6177            app.resetPackageList(mProcessStats);
6178            app.unlinkDeathRecipient();
6179            startProcessLocked(app, "bind fail", processName);
6180            return false;
6181        }
6182
6183        // Remove this record from the list of starting applications.
6184        mPersistentStartingProcesses.remove(app);
6185        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6186                "Attach application locked removing on hold: " + app);
6187        mProcessesOnHold.remove(app);
6188
6189        boolean badApp = false;
6190        boolean didSomething = false;
6191
6192        // See if the top visible activity is waiting to run in this process...
6193        if (normalMode) {
6194            try {
6195                if (mStackSupervisor.attachApplicationLocked(app)) {
6196                    didSomething = true;
6197                }
6198            } catch (Exception e) {
6199                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6200                badApp = true;
6201            }
6202        }
6203
6204        // Find any services that should be running in this process...
6205        if (!badApp) {
6206            try {
6207                didSomething |= mServices.attachApplicationLocked(app, processName);
6208            } catch (Exception e) {
6209                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6210                badApp = true;
6211            }
6212        }
6213
6214        // Check if a next-broadcast receiver is in this process...
6215        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6216            try {
6217                didSomething |= sendPendingBroadcastsLocked(app);
6218            } catch (Exception e) {
6219                // If the app died trying to launch the receiver we declare it 'bad'
6220                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6221                badApp = true;
6222            }
6223        }
6224
6225        // Check whether the next backup agent is in this process...
6226        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6227            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6228            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6229            try {
6230                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6231                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6232                        mBackupTarget.backupMode);
6233            } catch (Exception e) {
6234                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6235                badApp = true;
6236            }
6237        }
6238
6239        if (badApp) {
6240            app.kill("error during init", true);
6241            handleAppDiedLocked(app, false, true);
6242            return false;
6243        }
6244
6245        if (!didSomething) {
6246            updateOomAdjLocked();
6247        }
6248
6249        return true;
6250    }
6251
6252    @Override
6253    public final void attachApplication(IApplicationThread thread) {
6254        synchronized (this) {
6255            int callingPid = Binder.getCallingPid();
6256            final long origId = Binder.clearCallingIdentity();
6257            attachApplicationLocked(thread, callingPid);
6258            Binder.restoreCallingIdentity(origId);
6259        }
6260    }
6261
6262    @Override
6263    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6264        final long origId = Binder.clearCallingIdentity();
6265        synchronized (this) {
6266            ActivityStack stack = ActivityRecord.getStackLocked(token);
6267            if (stack != null) {
6268                ActivityRecord r =
6269                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6270                if (stopProfiling) {
6271                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6272                        try {
6273                            mProfileFd.close();
6274                        } catch (IOException e) {
6275                        }
6276                        clearProfilerLocked();
6277                    }
6278                }
6279            }
6280        }
6281        Binder.restoreCallingIdentity(origId);
6282    }
6283
6284    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6285        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6286                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6287    }
6288
6289    void enableScreenAfterBoot() {
6290        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6291                SystemClock.uptimeMillis());
6292        mWindowManager.enableScreenAfterBoot();
6293
6294        synchronized (this) {
6295            updateEventDispatchingLocked();
6296        }
6297    }
6298
6299    @Override
6300    public void showBootMessage(final CharSequence msg, final boolean always) {
6301        enforceNotIsolatedCaller("showBootMessage");
6302        mWindowManager.showBootMessage(msg, always);
6303    }
6304
6305    @Override
6306    public void keyguardWaitingForActivityDrawn() {
6307        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6308        final long token = Binder.clearCallingIdentity();
6309        try {
6310            synchronized (this) {
6311                if (DEBUG_LOCKSCREEN) logLockScreen("");
6312                mWindowManager.keyguardWaitingForActivityDrawn();
6313                if (mLockScreenShown) {
6314                    mLockScreenShown = false;
6315                    comeOutOfSleepIfNeededLocked();
6316                }
6317            }
6318        } finally {
6319            Binder.restoreCallingIdentity(token);
6320        }
6321    }
6322
6323    final void finishBooting() {
6324        synchronized (this) {
6325            if (!mBootAnimationComplete) {
6326                mCallFinishBooting = true;
6327                return;
6328            }
6329            mCallFinishBooting = false;
6330        }
6331
6332        // Register receivers to handle package update events
6333        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6334
6335        // Let system services know.
6336        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6337
6338        synchronized (this) {
6339            // Ensure that any processes we had put on hold are now started
6340            // up.
6341            final int NP = mProcessesOnHold.size();
6342            if (NP > 0) {
6343                ArrayList<ProcessRecord> procs =
6344                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6345                for (int ip=0; ip<NP; ip++) {
6346                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6347                            + procs.get(ip));
6348                    startProcessLocked(procs.get(ip), "on-hold", null);
6349                }
6350            }
6351
6352            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6353                // Start looking for apps that are abusing wake locks.
6354                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6355                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6356                // Tell anyone interested that we are done booting!
6357                SystemProperties.set("sys.boot_completed", "1");
6358
6359                // And trigger dev.bootcomplete if we are not showing encryption progress
6360                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6361                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6362                    SystemProperties.set("dev.bootcomplete", "1");
6363                }
6364                for (int i=0; i<mStartedUsers.size(); i++) {
6365                    UserStartedState uss = mStartedUsers.valueAt(i);
6366                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6367                        uss.mState = UserStartedState.STATE_RUNNING;
6368                        final int userId = mStartedUsers.keyAt(i);
6369                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6370                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6371                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6372                        broadcastIntentLocked(null, null, intent, null,
6373                                new IIntentReceiver.Stub() {
6374                                    @Override
6375                                    public void performReceive(Intent intent, int resultCode,
6376                                            String data, Bundle extras, boolean ordered,
6377                                            boolean sticky, int sendingUser) {
6378                                        synchronized (ActivityManagerService.this) {
6379                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6380                                                    true, false);
6381                                        }
6382                                    }
6383                                },
6384                                0, null, null,
6385                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6386                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6387                                userId);
6388                    }
6389                }
6390                scheduleStartProfilesLocked();
6391            }
6392        }
6393    }
6394
6395    @Override
6396    public void bootAnimationComplete() {
6397        final boolean callFinishBooting;
6398        synchronized (this) {
6399            callFinishBooting = mCallFinishBooting;
6400            mBootAnimationComplete = true;
6401        }
6402        if (callFinishBooting) {
6403            finishBooting();
6404        }
6405    }
6406
6407    final void ensureBootCompleted() {
6408        boolean booting;
6409        boolean enableScreen;
6410        synchronized (this) {
6411            booting = mBooting;
6412            mBooting = false;
6413            enableScreen = !mBooted;
6414            mBooted = true;
6415        }
6416
6417        if (booting) {
6418            finishBooting();
6419        }
6420
6421        if (enableScreen) {
6422            enableScreenAfterBoot();
6423        }
6424    }
6425
6426    @Override
6427    public final void activityResumed(IBinder token) {
6428        final long origId = Binder.clearCallingIdentity();
6429        synchronized(this) {
6430            ActivityStack stack = ActivityRecord.getStackLocked(token);
6431            if (stack != null) {
6432                ActivityRecord.activityResumedLocked(token);
6433            }
6434        }
6435        Binder.restoreCallingIdentity(origId);
6436    }
6437
6438    @Override
6439    public final void activityPaused(IBinder token) {
6440        final long origId = Binder.clearCallingIdentity();
6441        synchronized(this) {
6442            ActivityStack stack = ActivityRecord.getStackLocked(token);
6443            if (stack != null) {
6444                stack.activityPausedLocked(token, false);
6445            }
6446        }
6447        Binder.restoreCallingIdentity(origId);
6448    }
6449
6450    @Override
6451    public final void activityStopped(IBinder token, Bundle icicle,
6452            PersistableBundle persistentState, CharSequence description) {
6453        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6454
6455        // Refuse possible leaked file descriptors
6456        if (icicle != null && icicle.hasFileDescriptors()) {
6457            throw new IllegalArgumentException("File descriptors passed in Bundle");
6458        }
6459
6460        final long origId = Binder.clearCallingIdentity();
6461
6462        synchronized (this) {
6463            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6464            if (r != null) {
6465                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6466            }
6467        }
6468
6469        trimApplications();
6470
6471        Binder.restoreCallingIdentity(origId);
6472    }
6473
6474    @Override
6475    public final void activityDestroyed(IBinder token) {
6476        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6477        synchronized (this) {
6478            ActivityStack stack = ActivityRecord.getStackLocked(token);
6479            if (stack != null) {
6480                stack.activityDestroyedLocked(token);
6481            }
6482        }
6483    }
6484
6485    @Override
6486    public final void backgroundResourcesReleased(IBinder token) {
6487        final long origId = Binder.clearCallingIdentity();
6488        try {
6489            synchronized (this) {
6490                ActivityStack stack = ActivityRecord.getStackLocked(token);
6491                if (stack != null) {
6492                    stack.backgroundResourcesReleased(token);
6493                }
6494            }
6495        } finally {
6496            Binder.restoreCallingIdentity(origId);
6497        }
6498    }
6499
6500    @Override
6501    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6502        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6503    }
6504
6505    @Override
6506    public final void notifyEnterAnimationComplete(IBinder token) {
6507        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6508    }
6509
6510    @Override
6511    public String getCallingPackage(IBinder token) {
6512        synchronized (this) {
6513            ActivityRecord r = getCallingRecordLocked(token);
6514            return r != null ? r.info.packageName : null;
6515        }
6516    }
6517
6518    @Override
6519    public ComponentName getCallingActivity(IBinder token) {
6520        synchronized (this) {
6521            ActivityRecord r = getCallingRecordLocked(token);
6522            return r != null ? r.intent.getComponent() : null;
6523        }
6524    }
6525
6526    private ActivityRecord getCallingRecordLocked(IBinder token) {
6527        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6528        if (r == null) {
6529            return null;
6530        }
6531        return r.resultTo;
6532    }
6533
6534    @Override
6535    public ComponentName getActivityClassForToken(IBinder token) {
6536        synchronized(this) {
6537            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6538            if (r == null) {
6539                return null;
6540            }
6541            return r.intent.getComponent();
6542        }
6543    }
6544
6545    @Override
6546    public String getPackageForToken(IBinder token) {
6547        synchronized(this) {
6548            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6549            if (r == null) {
6550                return null;
6551            }
6552            return r.packageName;
6553        }
6554    }
6555
6556    @Override
6557    public IIntentSender getIntentSender(int type,
6558            String packageName, IBinder token, String resultWho,
6559            int requestCode, Intent[] intents, String[] resolvedTypes,
6560            int flags, Bundle options, int userId) {
6561        enforceNotIsolatedCaller("getIntentSender");
6562        // Refuse possible leaked file descriptors
6563        if (intents != null) {
6564            if (intents.length < 1) {
6565                throw new IllegalArgumentException("Intents array length must be >= 1");
6566            }
6567            for (int i=0; i<intents.length; i++) {
6568                Intent intent = intents[i];
6569                if (intent != null) {
6570                    if (intent.hasFileDescriptors()) {
6571                        throw new IllegalArgumentException("File descriptors passed in Intent");
6572                    }
6573                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6574                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6575                        throw new IllegalArgumentException(
6576                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6577                    }
6578                    intents[i] = new Intent(intent);
6579                }
6580            }
6581            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6582                throw new IllegalArgumentException(
6583                        "Intent array length does not match resolvedTypes length");
6584            }
6585        }
6586        if (options != null) {
6587            if (options.hasFileDescriptors()) {
6588                throw new IllegalArgumentException("File descriptors passed in options");
6589            }
6590        }
6591
6592        synchronized(this) {
6593            int callingUid = Binder.getCallingUid();
6594            int origUserId = userId;
6595            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6596                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6597                    ALLOW_NON_FULL, "getIntentSender", null);
6598            if (origUserId == UserHandle.USER_CURRENT) {
6599                // We don't want to evaluate this until the pending intent is
6600                // actually executed.  However, we do want to always do the
6601                // security checking for it above.
6602                userId = UserHandle.USER_CURRENT;
6603            }
6604            try {
6605                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6606                    int uid = AppGlobals.getPackageManager()
6607                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6608                    if (!UserHandle.isSameApp(callingUid, uid)) {
6609                        String msg = "Permission Denial: getIntentSender() from pid="
6610                            + Binder.getCallingPid()
6611                            + ", uid=" + Binder.getCallingUid()
6612                            + ", (need uid=" + uid + ")"
6613                            + " is not allowed to send as package " + packageName;
6614                        Slog.w(TAG, msg);
6615                        throw new SecurityException(msg);
6616                    }
6617                }
6618
6619                return getIntentSenderLocked(type, packageName, callingUid, userId,
6620                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6621
6622            } catch (RemoteException e) {
6623                throw new SecurityException(e);
6624            }
6625        }
6626    }
6627
6628    IIntentSender getIntentSenderLocked(int type, String packageName,
6629            int callingUid, int userId, IBinder token, String resultWho,
6630            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6631            Bundle options) {
6632        if (DEBUG_MU)
6633            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6634        ActivityRecord activity = null;
6635        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6636            activity = ActivityRecord.isInStackLocked(token);
6637            if (activity == null) {
6638                return null;
6639            }
6640            if (activity.finishing) {
6641                return null;
6642            }
6643        }
6644
6645        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6646        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6647        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6648        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6649                |PendingIntent.FLAG_UPDATE_CURRENT);
6650
6651        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6652                type, packageName, activity, resultWho,
6653                requestCode, intents, resolvedTypes, flags, options, userId);
6654        WeakReference<PendingIntentRecord> ref;
6655        ref = mIntentSenderRecords.get(key);
6656        PendingIntentRecord rec = ref != null ? ref.get() : null;
6657        if (rec != null) {
6658            if (!cancelCurrent) {
6659                if (updateCurrent) {
6660                    if (rec.key.requestIntent != null) {
6661                        rec.key.requestIntent.replaceExtras(intents != null ?
6662                                intents[intents.length - 1] : null);
6663                    }
6664                    if (intents != null) {
6665                        intents[intents.length-1] = rec.key.requestIntent;
6666                        rec.key.allIntents = intents;
6667                        rec.key.allResolvedTypes = resolvedTypes;
6668                    } else {
6669                        rec.key.allIntents = null;
6670                        rec.key.allResolvedTypes = null;
6671                    }
6672                }
6673                return rec;
6674            }
6675            rec.canceled = true;
6676            mIntentSenderRecords.remove(key);
6677        }
6678        if (noCreate) {
6679            return rec;
6680        }
6681        rec = new PendingIntentRecord(this, key, callingUid);
6682        mIntentSenderRecords.put(key, rec.ref);
6683        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6684            if (activity.pendingResults == null) {
6685                activity.pendingResults
6686                        = new HashSet<WeakReference<PendingIntentRecord>>();
6687            }
6688            activity.pendingResults.add(rec.ref);
6689        }
6690        return rec;
6691    }
6692
6693    @Override
6694    public void cancelIntentSender(IIntentSender sender) {
6695        if (!(sender instanceof PendingIntentRecord)) {
6696            return;
6697        }
6698        synchronized(this) {
6699            PendingIntentRecord rec = (PendingIntentRecord)sender;
6700            try {
6701                int uid = AppGlobals.getPackageManager()
6702                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6703                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6704                    String msg = "Permission Denial: cancelIntentSender() from pid="
6705                        + Binder.getCallingPid()
6706                        + ", uid=" + Binder.getCallingUid()
6707                        + " is not allowed to cancel packges "
6708                        + rec.key.packageName;
6709                    Slog.w(TAG, msg);
6710                    throw new SecurityException(msg);
6711                }
6712            } catch (RemoteException e) {
6713                throw new SecurityException(e);
6714            }
6715            cancelIntentSenderLocked(rec, true);
6716        }
6717    }
6718
6719    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6720        rec.canceled = true;
6721        mIntentSenderRecords.remove(rec.key);
6722        if (cleanActivity && rec.key.activity != null) {
6723            rec.key.activity.pendingResults.remove(rec.ref);
6724        }
6725    }
6726
6727    @Override
6728    public String getPackageForIntentSender(IIntentSender pendingResult) {
6729        if (!(pendingResult instanceof PendingIntentRecord)) {
6730            return null;
6731        }
6732        try {
6733            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6734            return res.key.packageName;
6735        } catch (ClassCastException e) {
6736        }
6737        return null;
6738    }
6739
6740    @Override
6741    public int getUidForIntentSender(IIntentSender sender) {
6742        if (sender instanceof PendingIntentRecord) {
6743            try {
6744                PendingIntentRecord res = (PendingIntentRecord)sender;
6745                return res.uid;
6746            } catch (ClassCastException e) {
6747            }
6748        }
6749        return -1;
6750    }
6751
6752    @Override
6753    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6754        if (!(pendingResult instanceof PendingIntentRecord)) {
6755            return false;
6756        }
6757        try {
6758            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6759            if (res.key.allIntents == null) {
6760                return false;
6761            }
6762            for (int i=0; i<res.key.allIntents.length; i++) {
6763                Intent intent = res.key.allIntents[i];
6764                if (intent.getPackage() != null && intent.getComponent() != null) {
6765                    return false;
6766                }
6767            }
6768            return true;
6769        } catch (ClassCastException e) {
6770        }
6771        return false;
6772    }
6773
6774    @Override
6775    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6776        if (!(pendingResult instanceof PendingIntentRecord)) {
6777            return false;
6778        }
6779        try {
6780            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6781            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6782                return true;
6783            }
6784            return false;
6785        } catch (ClassCastException e) {
6786        }
6787        return false;
6788    }
6789
6790    @Override
6791    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6792        if (!(pendingResult instanceof PendingIntentRecord)) {
6793            return null;
6794        }
6795        try {
6796            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6797            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6798        } catch (ClassCastException e) {
6799        }
6800        return null;
6801    }
6802
6803    @Override
6804    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6805        if (!(pendingResult instanceof PendingIntentRecord)) {
6806            return null;
6807        }
6808        try {
6809            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6810            Intent intent = res.key.requestIntent;
6811            if (intent != null) {
6812                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6813                        || res.lastTagPrefix.equals(prefix))) {
6814                    return res.lastTag;
6815                }
6816                res.lastTagPrefix = prefix;
6817                StringBuilder sb = new StringBuilder(128);
6818                if (prefix != null) {
6819                    sb.append(prefix);
6820                }
6821                if (intent.getAction() != null) {
6822                    sb.append(intent.getAction());
6823                } else if (intent.getComponent() != null) {
6824                    intent.getComponent().appendShortString(sb);
6825                } else {
6826                    sb.append("?");
6827                }
6828                return res.lastTag = sb.toString();
6829            }
6830        } catch (ClassCastException e) {
6831        }
6832        return null;
6833    }
6834
6835    @Override
6836    public void setProcessLimit(int max) {
6837        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6838                "setProcessLimit()");
6839        synchronized (this) {
6840            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6841            mProcessLimitOverride = max;
6842        }
6843        trimApplications();
6844    }
6845
6846    @Override
6847    public int getProcessLimit() {
6848        synchronized (this) {
6849            return mProcessLimitOverride;
6850        }
6851    }
6852
6853    void foregroundTokenDied(ForegroundToken token) {
6854        synchronized (ActivityManagerService.this) {
6855            synchronized (mPidsSelfLocked) {
6856                ForegroundToken cur
6857                    = mForegroundProcesses.get(token.pid);
6858                if (cur != token) {
6859                    return;
6860                }
6861                mForegroundProcesses.remove(token.pid);
6862                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6863                if (pr == null) {
6864                    return;
6865                }
6866                pr.forcingToForeground = null;
6867                updateProcessForegroundLocked(pr, false, false);
6868            }
6869            updateOomAdjLocked();
6870        }
6871    }
6872
6873    @Override
6874    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6875        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6876                "setProcessForeground()");
6877        synchronized(this) {
6878            boolean changed = false;
6879
6880            synchronized (mPidsSelfLocked) {
6881                ProcessRecord pr = mPidsSelfLocked.get(pid);
6882                if (pr == null && isForeground) {
6883                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6884                    return;
6885                }
6886                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6887                if (oldToken != null) {
6888                    oldToken.token.unlinkToDeath(oldToken, 0);
6889                    mForegroundProcesses.remove(pid);
6890                    if (pr != null) {
6891                        pr.forcingToForeground = null;
6892                    }
6893                    changed = true;
6894                }
6895                if (isForeground && token != null) {
6896                    ForegroundToken newToken = new ForegroundToken() {
6897                        @Override
6898                        public void binderDied() {
6899                            foregroundTokenDied(this);
6900                        }
6901                    };
6902                    newToken.pid = pid;
6903                    newToken.token = token;
6904                    try {
6905                        token.linkToDeath(newToken, 0);
6906                        mForegroundProcesses.put(pid, newToken);
6907                        pr.forcingToForeground = token;
6908                        changed = true;
6909                    } catch (RemoteException e) {
6910                        // If the process died while doing this, we will later
6911                        // do the cleanup with the process death link.
6912                    }
6913                }
6914            }
6915
6916            if (changed) {
6917                updateOomAdjLocked();
6918            }
6919        }
6920    }
6921
6922    // =========================================================
6923    // PERMISSIONS
6924    // =========================================================
6925
6926    static class PermissionController extends IPermissionController.Stub {
6927        ActivityManagerService mActivityManagerService;
6928        PermissionController(ActivityManagerService activityManagerService) {
6929            mActivityManagerService = activityManagerService;
6930        }
6931
6932        @Override
6933        public boolean checkPermission(String permission, int pid, int uid) {
6934            return mActivityManagerService.checkPermission(permission, pid,
6935                    uid) == PackageManager.PERMISSION_GRANTED;
6936        }
6937    }
6938
6939    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6940        @Override
6941        public int checkComponentPermission(String permission, int pid, int uid,
6942                int owningUid, boolean exported) {
6943            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6944                    owningUid, exported);
6945        }
6946
6947        @Override
6948        public Object getAMSLock() {
6949            return ActivityManagerService.this;
6950        }
6951    }
6952
6953    /**
6954     * This can be called with or without the global lock held.
6955     */
6956    int checkComponentPermission(String permission, int pid, int uid,
6957            int owningUid, boolean exported) {
6958        // We might be performing an operation on behalf of an indirect binder
6959        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6960        // client identity accordingly before proceeding.
6961        Identity tlsIdentity = sCallerIdentity.get();
6962        if (tlsIdentity != null) {
6963            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6964                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6965            uid = tlsIdentity.uid;
6966            pid = tlsIdentity.pid;
6967        }
6968
6969        if (pid == MY_PID) {
6970            return PackageManager.PERMISSION_GRANTED;
6971        }
6972
6973        return ActivityManager.checkComponentPermission(permission, uid,
6974                owningUid, exported);
6975    }
6976
6977    /**
6978     * As the only public entry point for permissions checking, this method
6979     * can enforce the semantic that requesting a check on a null global
6980     * permission is automatically denied.  (Internally a null permission
6981     * string is used when calling {@link #checkComponentPermission} in cases
6982     * when only uid-based security is needed.)
6983     *
6984     * This can be called with or without the global lock held.
6985     */
6986    @Override
6987    public int checkPermission(String permission, int pid, int uid) {
6988        if (permission == null) {
6989            return PackageManager.PERMISSION_DENIED;
6990        }
6991        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6992    }
6993
6994    /**
6995     * Binder IPC calls go through the public entry point.
6996     * This can be called with or without the global lock held.
6997     */
6998    int checkCallingPermission(String permission) {
6999        return checkPermission(permission,
7000                Binder.getCallingPid(),
7001                UserHandle.getAppId(Binder.getCallingUid()));
7002    }
7003
7004    /**
7005     * This can be called with or without the global lock held.
7006     */
7007    void enforceCallingPermission(String permission, String func) {
7008        if (checkCallingPermission(permission)
7009                == PackageManager.PERMISSION_GRANTED) {
7010            return;
7011        }
7012
7013        String msg = "Permission Denial: " + func + " from pid="
7014                + Binder.getCallingPid()
7015                + ", uid=" + Binder.getCallingUid()
7016                + " requires " + permission;
7017        Slog.w(TAG, msg);
7018        throw new SecurityException(msg);
7019    }
7020
7021    /**
7022     * Determine if UID is holding permissions required to access {@link Uri} in
7023     * the given {@link ProviderInfo}. Final permission checking is always done
7024     * in {@link ContentProvider}.
7025     */
7026    private final boolean checkHoldingPermissionsLocked(
7027            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7028        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7029                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7030        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7031            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7032                    != PERMISSION_GRANTED) {
7033                return false;
7034            }
7035        }
7036        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7037    }
7038
7039    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7040            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7041        if (pi.applicationInfo.uid == uid) {
7042            return true;
7043        } else if (!pi.exported) {
7044            return false;
7045        }
7046
7047        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7048        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7049        try {
7050            // check if target holds top-level <provider> permissions
7051            if (!readMet && pi.readPermission != null && considerUidPermissions
7052                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7053                readMet = true;
7054            }
7055            if (!writeMet && pi.writePermission != null && considerUidPermissions
7056                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7057                writeMet = true;
7058            }
7059
7060            // track if unprotected read/write is allowed; any denied
7061            // <path-permission> below removes this ability
7062            boolean allowDefaultRead = pi.readPermission == null;
7063            boolean allowDefaultWrite = pi.writePermission == null;
7064
7065            // check if target holds any <path-permission> that match uri
7066            final PathPermission[] pps = pi.pathPermissions;
7067            if (pps != null) {
7068                final String path = grantUri.uri.getPath();
7069                int i = pps.length;
7070                while (i > 0 && (!readMet || !writeMet)) {
7071                    i--;
7072                    PathPermission pp = pps[i];
7073                    if (pp.match(path)) {
7074                        if (!readMet) {
7075                            final String pprperm = pp.getReadPermission();
7076                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7077                                    + pprperm + " for " + pp.getPath()
7078                                    + ": match=" + pp.match(path)
7079                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7080                            if (pprperm != null) {
7081                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7082                                        == PERMISSION_GRANTED) {
7083                                    readMet = true;
7084                                } else {
7085                                    allowDefaultRead = false;
7086                                }
7087                            }
7088                        }
7089                        if (!writeMet) {
7090                            final String ppwperm = pp.getWritePermission();
7091                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7092                                    + ppwperm + " for " + pp.getPath()
7093                                    + ": match=" + pp.match(path)
7094                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7095                            if (ppwperm != null) {
7096                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7097                                        == PERMISSION_GRANTED) {
7098                                    writeMet = true;
7099                                } else {
7100                                    allowDefaultWrite = false;
7101                                }
7102                            }
7103                        }
7104                    }
7105                }
7106            }
7107
7108            // grant unprotected <provider> read/write, if not blocked by
7109            // <path-permission> above
7110            if (allowDefaultRead) readMet = true;
7111            if (allowDefaultWrite) writeMet = true;
7112
7113        } catch (RemoteException e) {
7114            return false;
7115        }
7116
7117        return readMet && writeMet;
7118    }
7119
7120    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7121        ProviderInfo pi = null;
7122        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7123        if (cpr != null) {
7124            pi = cpr.info;
7125        } else {
7126            try {
7127                pi = AppGlobals.getPackageManager().resolveContentProvider(
7128                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7129            } catch (RemoteException ex) {
7130            }
7131        }
7132        return pi;
7133    }
7134
7135    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7136        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7137        if (targetUris != null) {
7138            return targetUris.get(grantUri);
7139        }
7140        return null;
7141    }
7142
7143    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7144            String targetPkg, int targetUid, GrantUri grantUri) {
7145        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7146        if (targetUris == null) {
7147            targetUris = Maps.newArrayMap();
7148            mGrantedUriPermissions.put(targetUid, targetUris);
7149        }
7150
7151        UriPermission perm = targetUris.get(grantUri);
7152        if (perm == null) {
7153            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7154            targetUris.put(grantUri, perm);
7155        }
7156
7157        return perm;
7158    }
7159
7160    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7161            final int modeFlags) {
7162        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7163        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7164                : UriPermission.STRENGTH_OWNED;
7165
7166        // Root gets to do everything.
7167        if (uid == 0) {
7168            return true;
7169        }
7170
7171        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7172        if (perms == null) return false;
7173
7174        // First look for exact match
7175        final UriPermission exactPerm = perms.get(grantUri);
7176        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7177            return true;
7178        }
7179
7180        // No exact match, look for prefixes
7181        final int N = perms.size();
7182        for (int i = 0; i < N; i++) {
7183            final UriPermission perm = perms.valueAt(i);
7184            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7185                    && perm.getStrength(modeFlags) >= minStrength) {
7186                return true;
7187            }
7188        }
7189
7190        return false;
7191    }
7192
7193    /**
7194     * @param uri This uri must NOT contain an embedded userId.
7195     * @param userId The userId in which the uri is to be resolved.
7196     */
7197    @Override
7198    public int checkUriPermission(Uri uri, int pid, int uid,
7199            final int modeFlags, int userId) {
7200        enforceNotIsolatedCaller("checkUriPermission");
7201
7202        // Another redirected-binder-call permissions check as in
7203        // {@link checkComponentPermission}.
7204        Identity tlsIdentity = sCallerIdentity.get();
7205        if (tlsIdentity != null) {
7206            uid = tlsIdentity.uid;
7207            pid = tlsIdentity.pid;
7208        }
7209
7210        // Our own process gets to do everything.
7211        if (pid == MY_PID) {
7212            return PackageManager.PERMISSION_GRANTED;
7213        }
7214        synchronized (this) {
7215            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7216                    ? PackageManager.PERMISSION_GRANTED
7217                    : PackageManager.PERMISSION_DENIED;
7218        }
7219    }
7220
7221    /**
7222     * Check if the targetPkg can be granted permission to access uri by
7223     * the callingUid using the given modeFlags.  Throws a security exception
7224     * if callingUid is not allowed to do this.  Returns the uid of the target
7225     * if the URI permission grant should be performed; returns -1 if it is not
7226     * needed (for example targetPkg already has permission to access the URI).
7227     * If you already know the uid of the target, you can supply it in
7228     * lastTargetUid else set that to -1.
7229     */
7230    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7231            final int modeFlags, int lastTargetUid) {
7232        if (!Intent.isAccessUriMode(modeFlags)) {
7233            return -1;
7234        }
7235
7236        if (targetPkg != null) {
7237            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7238                    "Checking grant " + targetPkg + " permission to " + grantUri);
7239        }
7240
7241        final IPackageManager pm = AppGlobals.getPackageManager();
7242
7243        // If this is not a content: uri, we can't do anything with it.
7244        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7245            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7246                    "Can't grant URI permission for non-content URI: " + grantUri);
7247            return -1;
7248        }
7249
7250        final String authority = grantUri.uri.getAuthority();
7251        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7252        if (pi == null) {
7253            Slog.w(TAG, "No content provider found for permission check: " +
7254                    grantUri.uri.toSafeString());
7255            return -1;
7256        }
7257
7258        int targetUid = lastTargetUid;
7259        if (targetUid < 0 && targetPkg != null) {
7260            try {
7261                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7262                if (targetUid < 0) {
7263                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7264                            "Can't grant URI permission no uid for: " + targetPkg);
7265                    return -1;
7266                }
7267            } catch (RemoteException ex) {
7268                return -1;
7269            }
7270        }
7271
7272        if (targetUid >= 0) {
7273            // First...  does the target actually need this permission?
7274            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7275                // No need to grant the target this permission.
7276                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7277                        "Target " + targetPkg + " already has full permission to " + grantUri);
7278                return -1;
7279            }
7280        } else {
7281            // First...  there is no target package, so can anyone access it?
7282            boolean allowed = pi.exported;
7283            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7284                if (pi.readPermission != null) {
7285                    allowed = false;
7286                }
7287            }
7288            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7289                if (pi.writePermission != null) {
7290                    allowed = false;
7291                }
7292            }
7293            if (allowed) {
7294                return -1;
7295            }
7296        }
7297
7298        /* There is a special cross user grant if:
7299         * - The target is on another user.
7300         * - Apps on the current user can access the uri without any uid permissions.
7301         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7302         * grant uri permissions.
7303         */
7304        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7305                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7306                modeFlags, false /*without considering the uid permissions*/);
7307
7308        // Second...  is the provider allowing granting of URI permissions?
7309        if (!specialCrossUserGrant) {
7310            if (!pi.grantUriPermissions) {
7311                throw new SecurityException("Provider " + pi.packageName
7312                        + "/" + pi.name
7313                        + " does not allow granting of Uri permissions (uri "
7314                        + grantUri + ")");
7315            }
7316            if (pi.uriPermissionPatterns != null) {
7317                final int N = pi.uriPermissionPatterns.length;
7318                boolean allowed = false;
7319                for (int i=0; i<N; i++) {
7320                    if (pi.uriPermissionPatterns[i] != null
7321                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7322                        allowed = true;
7323                        break;
7324                    }
7325                }
7326                if (!allowed) {
7327                    throw new SecurityException("Provider " + pi.packageName
7328                            + "/" + pi.name
7329                            + " does not allow granting of permission to path of Uri "
7330                            + grantUri);
7331                }
7332            }
7333        }
7334
7335        // Third...  does the caller itself have permission to access
7336        // this uri?
7337        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7338            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7339                // Require they hold a strong enough Uri permission
7340                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7341                    throw new SecurityException("Uid " + callingUid
7342                            + " does not have permission to uri " + grantUri);
7343                }
7344            }
7345        }
7346        return targetUid;
7347    }
7348
7349    /**
7350     * @param uri This uri must NOT contain an embedded userId.
7351     * @param userId The userId in which the uri is to be resolved.
7352     */
7353    @Override
7354    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7355            final int modeFlags, int userId) {
7356        enforceNotIsolatedCaller("checkGrantUriPermission");
7357        synchronized(this) {
7358            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7359                    new GrantUri(userId, uri, false), modeFlags, -1);
7360        }
7361    }
7362
7363    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7364            final int modeFlags, UriPermissionOwner owner) {
7365        if (!Intent.isAccessUriMode(modeFlags)) {
7366            return;
7367        }
7368
7369        // So here we are: the caller has the assumed permission
7370        // to the uri, and the target doesn't.  Let's now give this to
7371        // the target.
7372
7373        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7374                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7375
7376        final String authority = grantUri.uri.getAuthority();
7377        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7378        if (pi == null) {
7379            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7380            return;
7381        }
7382
7383        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7384            grantUri.prefix = true;
7385        }
7386        final UriPermission perm = findOrCreateUriPermissionLocked(
7387                pi.packageName, targetPkg, targetUid, grantUri);
7388        perm.grantModes(modeFlags, owner);
7389    }
7390
7391    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7392            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7393        if (targetPkg == null) {
7394            throw new NullPointerException("targetPkg");
7395        }
7396        int targetUid;
7397        final IPackageManager pm = AppGlobals.getPackageManager();
7398        try {
7399            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7400        } catch (RemoteException ex) {
7401            return;
7402        }
7403
7404        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7405                targetUid);
7406        if (targetUid < 0) {
7407            return;
7408        }
7409
7410        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7411                owner);
7412    }
7413
7414    static class NeededUriGrants extends ArrayList<GrantUri> {
7415        final String targetPkg;
7416        final int targetUid;
7417        final int flags;
7418
7419        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7420            this.targetPkg = targetPkg;
7421            this.targetUid = targetUid;
7422            this.flags = flags;
7423        }
7424    }
7425
7426    /**
7427     * Like checkGrantUriPermissionLocked, but takes an Intent.
7428     */
7429    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7430            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7431        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7432                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7433                + " clip=" + (intent != null ? intent.getClipData() : null)
7434                + " from " + intent + "; flags=0x"
7435                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7436
7437        if (targetPkg == null) {
7438            throw new NullPointerException("targetPkg");
7439        }
7440
7441        if (intent == null) {
7442            return null;
7443        }
7444        Uri data = intent.getData();
7445        ClipData clip = intent.getClipData();
7446        if (data == null && clip == null) {
7447            return null;
7448        }
7449        // Default userId for uris in the intent (if they don't specify it themselves)
7450        int contentUserHint = intent.getContentUserHint();
7451        if (contentUserHint == UserHandle.USER_CURRENT) {
7452            contentUserHint = UserHandle.getUserId(callingUid);
7453        }
7454        final IPackageManager pm = AppGlobals.getPackageManager();
7455        int targetUid;
7456        if (needed != null) {
7457            targetUid = needed.targetUid;
7458        } else {
7459            try {
7460                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7461            } catch (RemoteException ex) {
7462                return null;
7463            }
7464            if (targetUid < 0) {
7465                if (DEBUG_URI_PERMISSION) {
7466                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7467                            + " on user " + targetUserId);
7468                }
7469                return null;
7470            }
7471        }
7472        if (data != null) {
7473            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7474            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7475                    targetUid);
7476            if (targetUid > 0) {
7477                if (needed == null) {
7478                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7479                }
7480                needed.add(grantUri);
7481            }
7482        }
7483        if (clip != null) {
7484            for (int i=0; i<clip.getItemCount(); i++) {
7485                Uri uri = clip.getItemAt(i).getUri();
7486                if (uri != null) {
7487                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7488                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7489                            targetUid);
7490                    if (targetUid > 0) {
7491                        if (needed == null) {
7492                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7493                        }
7494                        needed.add(grantUri);
7495                    }
7496                } else {
7497                    Intent clipIntent = clip.getItemAt(i).getIntent();
7498                    if (clipIntent != null) {
7499                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7500                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7501                        if (newNeeded != null) {
7502                            needed = newNeeded;
7503                        }
7504                    }
7505                }
7506            }
7507        }
7508
7509        return needed;
7510    }
7511
7512    /**
7513     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7514     */
7515    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7516            UriPermissionOwner owner) {
7517        if (needed != null) {
7518            for (int i=0; i<needed.size(); i++) {
7519                GrantUri grantUri = needed.get(i);
7520                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7521                        grantUri, needed.flags, owner);
7522            }
7523        }
7524    }
7525
7526    void grantUriPermissionFromIntentLocked(int callingUid,
7527            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7528        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7529                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7530        if (needed == null) {
7531            return;
7532        }
7533
7534        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7535    }
7536
7537    /**
7538     * @param uri This uri must NOT contain an embedded userId.
7539     * @param userId The userId in which the uri is to be resolved.
7540     */
7541    @Override
7542    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7543            final int modeFlags, int userId) {
7544        enforceNotIsolatedCaller("grantUriPermission");
7545        GrantUri grantUri = new GrantUri(userId, uri, false);
7546        synchronized(this) {
7547            final ProcessRecord r = getRecordForAppLocked(caller);
7548            if (r == null) {
7549                throw new SecurityException("Unable to find app for caller "
7550                        + caller
7551                        + " when granting permission to uri " + grantUri);
7552            }
7553            if (targetPkg == null) {
7554                throw new IllegalArgumentException("null target");
7555            }
7556            if (grantUri == null) {
7557                throw new IllegalArgumentException("null uri");
7558            }
7559
7560            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7561                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7562                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7563                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7564
7565            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7566                    UserHandle.getUserId(r.uid));
7567        }
7568    }
7569
7570    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7571        if (perm.modeFlags == 0) {
7572            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7573                    perm.targetUid);
7574            if (perms != null) {
7575                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7576                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7577
7578                perms.remove(perm.uri);
7579                if (perms.isEmpty()) {
7580                    mGrantedUriPermissions.remove(perm.targetUid);
7581                }
7582            }
7583        }
7584    }
7585
7586    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7587        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7588
7589        final IPackageManager pm = AppGlobals.getPackageManager();
7590        final String authority = grantUri.uri.getAuthority();
7591        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7592        if (pi == null) {
7593            Slog.w(TAG, "No content provider found for permission revoke: "
7594                    + grantUri.toSafeString());
7595            return;
7596        }
7597
7598        // Does the caller have this permission on the URI?
7599        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7600            // If they don't have direct access to the URI, then revoke any
7601            // ownerless URI permissions that have been granted to them.
7602            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7603            if (perms != null) {
7604                boolean persistChanged = false;
7605                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7606                    final UriPermission perm = it.next();
7607                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7608                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7609                        if (DEBUG_URI_PERMISSION)
7610                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7611                                    " permission to " + perm.uri);
7612                        persistChanged |= perm.revokeModes(
7613                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7614                        if (perm.modeFlags == 0) {
7615                            it.remove();
7616                        }
7617                    }
7618                }
7619                if (perms.isEmpty()) {
7620                    mGrantedUriPermissions.remove(callingUid);
7621                }
7622                if (persistChanged) {
7623                    schedulePersistUriGrants();
7624                }
7625            }
7626            return;
7627        }
7628
7629        boolean persistChanged = false;
7630
7631        // Go through all of the permissions and remove any that match.
7632        int N = mGrantedUriPermissions.size();
7633        for (int i = 0; i < N; i++) {
7634            final int targetUid = mGrantedUriPermissions.keyAt(i);
7635            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7636
7637            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7638                final UriPermission perm = it.next();
7639                if (perm.uri.sourceUserId == grantUri.sourceUserId
7640                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7641                    if (DEBUG_URI_PERMISSION)
7642                        Slog.v(TAG,
7643                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7644                    persistChanged |= perm.revokeModes(
7645                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7646                    if (perm.modeFlags == 0) {
7647                        it.remove();
7648                    }
7649                }
7650            }
7651
7652            if (perms.isEmpty()) {
7653                mGrantedUriPermissions.remove(targetUid);
7654                N--;
7655                i--;
7656            }
7657        }
7658
7659        if (persistChanged) {
7660            schedulePersistUriGrants();
7661        }
7662    }
7663
7664    /**
7665     * @param uri This uri must NOT contain an embedded userId.
7666     * @param userId The userId in which the uri is to be resolved.
7667     */
7668    @Override
7669    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7670            int userId) {
7671        enforceNotIsolatedCaller("revokeUriPermission");
7672        synchronized(this) {
7673            final ProcessRecord r = getRecordForAppLocked(caller);
7674            if (r == null) {
7675                throw new SecurityException("Unable to find app for caller "
7676                        + caller
7677                        + " when revoking permission to uri " + uri);
7678            }
7679            if (uri == null) {
7680                Slog.w(TAG, "revokeUriPermission: null uri");
7681                return;
7682            }
7683
7684            if (!Intent.isAccessUriMode(modeFlags)) {
7685                return;
7686            }
7687
7688            final IPackageManager pm = AppGlobals.getPackageManager();
7689            final String authority = uri.getAuthority();
7690            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7691            if (pi == null) {
7692                Slog.w(TAG, "No content provider found for permission revoke: "
7693                        + uri.toSafeString());
7694                return;
7695            }
7696
7697            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7698        }
7699    }
7700
7701    /**
7702     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7703     * given package.
7704     *
7705     * @param packageName Package name to match, or {@code null} to apply to all
7706     *            packages.
7707     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7708     *            to all users.
7709     * @param persistable If persistable grants should be removed.
7710     */
7711    private void removeUriPermissionsForPackageLocked(
7712            String packageName, int userHandle, boolean persistable) {
7713        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7714            throw new IllegalArgumentException("Must narrow by either package or user");
7715        }
7716
7717        boolean persistChanged = false;
7718
7719        int N = mGrantedUriPermissions.size();
7720        for (int i = 0; i < N; i++) {
7721            final int targetUid = mGrantedUriPermissions.keyAt(i);
7722            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7723
7724            // Only inspect grants matching user
7725            if (userHandle == UserHandle.USER_ALL
7726                    || userHandle == UserHandle.getUserId(targetUid)) {
7727                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7728                    final UriPermission perm = it.next();
7729
7730                    // Only inspect grants matching package
7731                    if (packageName == null || perm.sourcePkg.equals(packageName)
7732                            || perm.targetPkg.equals(packageName)) {
7733                        persistChanged |= perm.revokeModes(persistable
7734                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7735
7736                        // Only remove when no modes remain; any persisted grants
7737                        // will keep this alive.
7738                        if (perm.modeFlags == 0) {
7739                            it.remove();
7740                        }
7741                    }
7742                }
7743
7744                if (perms.isEmpty()) {
7745                    mGrantedUriPermissions.remove(targetUid);
7746                    N--;
7747                    i--;
7748                }
7749            }
7750        }
7751
7752        if (persistChanged) {
7753            schedulePersistUriGrants();
7754        }
7755    }
7756
7757    @Override
7758    public IBinder newUriPermissionOwner(String name) {
7759        enforceNotIsolatedCaller("newUriPermissionOwner");
7760        synchronized(this) {
7761            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7762            return owner.getExternalTokenLocked();
7763        }
7764    }
7765
7766    /**
7767     * @param uri This uri must NOT contain an embedded userId.
7768     * @param sourceUserId The userId in which the uri is to be resolved.
7769     * @param targetUserId The userId of the app that receives the grant.
7770     */
7771    @Override
7772    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7773            final int modeFlags, int sourceUserId, int targetUserId) {
7774        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7775                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7776        synchronized(this) {
7777            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7778            if (owner == null) {
7779                throw new IllegalArgumentException("Unknown owner: " + token);
7780            }
7781            if (fromUid != Binder.getCallingUid()) {
7782                if (Binder.getCallingUid() != Process.myUid()) {
7783                    // Only system code can grant URI permissions on behalf
7784                    // of other users.
7785                    throw new SecurityException("nice try");
7786                }
7787            }
7788            if (targetPkg == null) {
7789                throw new IllegalArgumentException("null target");
7790            }
7791            if (uri == null) {
7792                throw new IllegalArgumentException("null uri");
7793            }
7794
7795            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7796                    modeFlags, owner, targetUserId);
7797        }
7798    }
7799
7800    /**
7801     * @param uri This uri must NOT contain an embedded userId.
7802     * @param userId The userId in which the uri is to be resolved.
7803     */
7804    @Override
7805    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7806        synchronized(this) {
7807            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7808            if (owner == null) {
7809                throw new IllegalArgumentException("Unknown owner: " + token);
7810            }
7811
7812            if (uri == null) {
7813                owner.removeUriPermissionsLocked(mode);
7814            } else {
7815                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7816            }
7817        }
7818    }
7819
7820    private void schedulePersistUriGrants() {
7821        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7822            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7823                    10 * DateUtils.SECOND_IN_MILLIS);
7824        }
7825    }
7826
7827    private void writeGrantedUriPermissions() {
7828        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7829
7830        // Snapshot permissions so we can persist without lock
7831        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7832        synchronized (this) {
7833            final int size = mGrantedUriPermissions.size();
7834            for (int i = 0; i < size; i++) {
7835                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7836                for (UriPermission perm : perms.values()) {
7837                    if (perm.persistedModeFlags != 0) {
7838                        persist.add(perm.snapshot());
7839                    }
7840                }
7841            }
7842        }
7843
7844        FileOutputStream fos = null;
7845        try {
7846            fos = mGrantFile.startWrite();
7847
7848            XmlSerializer out = new FastXmlSerializer();
7849            out.setOutput(fos, "utf-8");
7850            out.startDocument(null, true);
7851            out.startTag(null, TAG_URI_GRANTS);
7852            for (UriPermission.Snapshot perm : persist) {
7853                out.startTag(null, TAG_URI_GRANT);
7854                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7855                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7856                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7857                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7858                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7859                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7860                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7861                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7862                out.endTag(null, TAG_URI_GRANT);
7863            }
7864            out.endTag(null, TAG_URI_GRANTS);
7865            out.endDocument();
7866
7867            mGrantFile.finishWrite(fos);
7868        } catch (IOException e) {
7869            if (fos != null) {
7870                mGrantFile.failWrite(fos);
7871            }
7872        }
7873    }
7874
7875    private void readGrantedUriPermissionsLocked() {
7876        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7877
7878        final long now = System.currentTimeMillis();
7879
7880        FileInputStream fis = null;
7881        try {
7882            fis = mGrantFile.openRead();
7883            final XmlPullParser in = Xml.newPullParser();
7884            in.setInput(fis, null);
7885
7886            int type;
7887            while ((type = in.next()) != END_DOCUMENT) {
7888                final String tag = in.getName();
7889                if (type == START_TAG) {
7890                    if (TAG_URI_GRANT.equals(tag)) {
7891                        final int sourceUserId;
7892                        final int targetUserId;
7893                        final int userHandle = readIntAttribute(in,
7894                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7895                        if (userHandle != UserHandle.USER_NULL) {
7896                            // For backwards compatibility.
7897                            sourceUserId = userHandle;
7898                            targetUserId = userHandle;
7899                        } else {
7900                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7901                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7902                        }
7903                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7904                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7905                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7906                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7907                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7908                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7909
7910                        // Sanity check that provider still belongs to source package
7911                        final ProviderInfo pi = getProviderInfoLocked(
7912                                uri.getAuthority(), sourceUserId);
7913                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7914                            int targetUid = -1;
7915                            try {
7916                                targetUid = AppGlobals.getPackageManager()
7917                                        .getPackageUid(targetPkg, targetUserId);
7918                            } catch (RemoteException e) {
7919                            }
7920                            if (targetUid != -1) {
7921                                final UriPermission perm = findOrCreateUriPermissionLocked(
7922                                        sourcePkg, targetPkg, targetUid,
7923                                        new GrantUri(sourceUserId, uri, prefix));
7924                                perm.initPersistedModes(modeFlags, createdTime);
7925                            }
7926                        } else {
7927                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7928                                    + " but instead found " + pi);
7929                        }
7930                    }
7931                }
7932            }
7933        } catch (FileNotFoundException e) {
7934            // Missing grants is okay
7935        } catch (IOException e) {
7936            Slog.wtf(TAG, "Failed reading Uri grants", e);
7937        } catch (XmlPullParserException e) {
7938            Slog.wtf(TAG, "Failed reading Uri grants", e);
7939        } finally {
7940            IoUtils.closeQuietly(fis);
7941        }
7942    }
7943
7944    /**
7945     * @param uri This uri must NOT contain an embedded userId.
7946     * @param userId The userId in which the uri is to be resolved.
7947     */
7948    @Override
7949    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7950        enforceNotIsolatedCaller("takePersistableUriPermission");
7951
7952        Preconditions.checkFlagsArgument(modeFlags,
7953                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7954
7955        synchronized (this) {
7956            final int callingUid = Binder.getCallingUid();
7957            boolean persistChanged = false;
7958            GrantUri grantUri = new GrantUri(userId, uri, false);
7959
7960            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7961                    new GrantUri(userId, uri, false));
7962            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7963                    new GrantUri(userId, uri, true));
7964
7965            final boolean exactValid = (exactPerm != null)
7966                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7967            final boolean prefixValid = (prefixPerm != null)
7968                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7969
7970            if (!(exactValid || prefixValid)) {
7971                throw new SecurityException("No persistable permission grants found for UID "
7972                        + callingUid + " and Uri " + grantUri.toSafeString());
7973            }
7974
7975            if (exactValid) {
7976                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7977            }
7978            if (prefixValid) {
7979                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7980            }
7981
7982            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7983
7984            if (persistChanged) {
7985                schedulePersistUriGrants();
7986            }
7987        }
7988    }
7989
7990    /**
7991     * @param uri This uri must NOT contain an embedded userId.
7992     * @param userId The userId in which the uri is to be resolved.
7993     */
7994    @Override
7995    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7996        enforceNotIsolatedCaller("releasePersistableUriPermission");
7997
7998        Preconditions.checkFlagsArgument(modeFlags,
7999                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8000
8001        synchronized (this) {
8002            final int callingUid = Binder.getCallingUid();
8003            boolean persistChanged = false;
8004
8005            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8006                    new GrantUri(userId, uri, false));
8007            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8008                    new GrantUri(userId, uri, true));
8009            if (exactPerm == null && prefixPerm == null) {
8010                throw new SecurityException("No permission grants found for UID " + callingUid
8011                        + " and Uri " + uri.toSafeString());
8012            }
8013
8014            if (exactPerm != null) {
8015                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8016                removeUriPermissionIfNeededLocked(exactPerm);
8017            }
8018            if (prefixPerm != null) {
8019                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8020                removeUriPermissionIfNeededLocked(prefixPerm);
8021            }
8022
8023            if (persistChanged) {
8024                schedulePersistUriGrants();
8025            }
8026        }
8027    }
8028
8029    /**
8030     * Prune any older {@link UriPermission} for the given UID until outstanding
8031     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8032     *
8033     * @return if any mutations occured that require persisting.
8034     */
8035    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8036        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8037        if (perms == null) return false;
8038        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8039
8040        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8041        for (UriPermission perm : perms.values()) {
8042            if (perm.persistedModeFlags != 0) {
8043                persisted.add(perm);
8044            }
8045        }
8046
8047        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8048        if (trimCount <= 0) return false;
8049
8050        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8051        for (int i = 0; i < trimCount; i++) {
8052            final UriPermission perm = persisted.get(i);
8053
8054            if (DEBUG_URI_PERMISSION) {
8055                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8056            }
8057
8058            perm.releasePersistableModes(~0);
8059            removeUriPermissionIfNeededLocked(perm);
8060        }
8061
8062        return true;
8063    }
8064
8065    @Override
8066    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8067            String packageName, boolean incoming) {
8068        enforceNotIsolatedCaller("getPersistedUriPermissions");
8069        Preconditions.checkNotNull(packageName, "packageName");
8070
8071        final int callingUid = Binder.getCallingUid();
8072        final IPackageManager pm = AppGlobals.getPackageManager();
8073        try {
8074            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8075            if (packageUid != callingUid) {
8076                throw new SecurityException(
8077                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8078            }
8079        } catch (RemoteException e) {
8080            throw new SecurityException("Failed to verify package name ownership");
8081        }
8082
8083        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8084        synchronized (this) {
8085            if (incoming) {
8086                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8087                        callingUid);
8088                if (perms == null) {
8089                    Slog.w(TAG, "No permission grants found for " + packageName);
8090                } else {
8091                    for (UriPermission perm : perms.values()) {
8092                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8093                            result.add(perm.buildPersistedPublicApiObject());
8094                        }
8095                    }
8096                }
8097            } else {
8098                final int size = mGrantedUriPermissions.size();
8099                for (int i = 0; i < size; i++) {
8100                    final ArrayMap<GrantUri, UriPermission> perms =
8101                            mGrantedUriPermissions.valueAt(i);
8102                    for (UriPermission perm : perms.values()) {
8103                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8104                            result.add(perm.buildPersistedPublicApiObject());
8105                        }
8106                    }
8107                }
8108            }
8109        }
8110        return new ParceledListSlice<android.content.UriPermission>(result);
8111    }
8112
8113    @Override
8114    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8115        synchronized (this) {
8116            ProcessRecord app =
8117                who != null ? getRecordForAppLocked(who) : null;
8118            if (app == null) return;
8119
8120            Message msg = Message.obtain();
8121            msg.what = WAIT_FOR_DEBUGGER_MSG;
8122            msg.obj = app;
8123            msg.arg1 = waiting ? 1 : 0;
8124            mHandler.sendMessage(msg);
8125        }
8126    }
8127
8128    @Override
8129    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8130        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8131        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8132        outInfo.availMem = Process.getFreeMemory();
8133        outInfo.totalMem = Process.getTotalMemory();
8134        outInfo.threshold = homeAppMem;
8135        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8136        outInfo.hiddenAppThreshold = cachedAppMem;
8137        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8138                ProcessList.SERVICE_ADJ);
8139        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8140                ProcessList.VISIBLE_APP_ADJ);
8141        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8142                ProcessList.FOREGROUND_APP_ADJ);
8143    }
8144
8145    // =========================================================
8146    // TASK MANAGEMENT
8147    // =========================================================
8148
8149    @Override
8150    public List<IAppTask> getAppTasks(String callingPackage) {
8151        int callingUid = Binder.getCallingUid();
8152        long ident = Binder.clearCallingIdentity();
8153
8154        synchronized(this) {
8155            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8156            try {
8157                if (localLOGV) Slog.v(TAG, "getAppTasks");
8158
8159                final int N = mRecentTasks.size();
8160                for (int i = 0; i < N; i++) {
8161                    TaskRecord tr = mRecentTasks.get(i);
8162                    // Skip tasks that do not match the caller.  We don't need to verify
8163                    // callingPackage, because we are also limiting to callingUid and know
8164                    // that will limit to the correct security sandbox.
8165                    if (tr.effectiveUid != callingUid) {
8166                        continue;
8167                    }
8168                    Intent intent = tr.getBaseIntent();
8169                    if (intent == null ||
8170                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8171                        continue;
8172                    }
8173                    ActivityManager.RecentTaskInfo taskInfo =
8174                            createRecentTaskInfoFromTaskRecord(tr);
8175                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8176                    list.add(taskImpl);
8177                }
8178            } finally {
8179                Binder.restoreCallingIdentity(ident);
8180            }
8181            return list;
8182        }
8183    }
8184
8185    @Override
8186    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8187        final int callingUid = Binder.getCallingUid();
8188        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8189
8190        synchronized(this) {
8191            if (localLOGV) Slog.v(
8192                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8193
8194            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8195                    callingUid);
8196
8197            // TODO: Improve with MRU list from all ActivityStacks.
8198            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8199        }
8200
8201        return list;
8202    }
8203
8204    TaskRecord getMostRecentTask() {
8205        return mRecentTasks.get(0);
8206    }
8207
8208    /**
8209     * Creates a new RecentTaskInfo from a TaskRecord.
8210     */
8211    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8212        // Update the task description to reflect any changes in the task stack
8213        tr.updateTaskDescription();
8214
8215        // Compose the recent task info
8216        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8217        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8218        rti.persistentId = tr.taskId;
8219        rti.baseIntent = new Intent(tr.getBaseIntent());
8220        rti.origActivity = tr.origActivity;
8221        rti.description = tr.lastDescription;
8222        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8223        rti.userId = tr.userId;
8224        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8225        rti.firstActiveTime = tr.firstActiveTime;
8226        rti.lastActiveTime = tr.lastActiveTime;
8227        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8228        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8229        return rti;
8230    }
8231
8232    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8233        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8234                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8235        if (!allowed) {
8236            if (checkPermission(android.Manifest.permission.GET_TASKS,
8237                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8238                // Temporary compatibility: some existing apps on the system image may
8239                // still be requesting the old permission and not switched to the new
8240                // one; if so, we'll still allow them full access.  This means we need
8241                // to see if they are holding the old permission and are a system app.
8242                try {
8243                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8244                        allowed = true;
8245                        Slog.w(TAG, caller + ": caller " + callingUid
8246                                + " is using old GET_TASKS but privileged; allowing");
8247                    }
8248                } catch (RemoteException e) {
8249                }
8250            }
8251        }
8252        if (!allowed) {
8253            Slog.w(TAG, caller + ": caller " + callingUid
8254                    + " does not hold GET_TASKS; limiting output");
8255        }
8256        return allowed;
8257    }
8258
8259    @Override
8260    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8261        final int callingUid = Binder.getCallingUid();
8262        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8263                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8264
8265        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8266        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8267        synchronized (this) {
8268            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8269                    callingUid);
8270            final boolean detailed = checkCallingPermission(
8271                    android.Manifest.permission.GET_DETAILED_TASKS)
8272                    == PackageManager.PERMISSION_GRANTED;
8273
8274            final int N = mRecentTasks.size();
8275            ArrayList<ActivityManager.RecentTaskInfo> res
8276                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8277                            maxNum < N ? maxNum : N);
8278
8279            final Set<Integer> includedUsers;
8280            if (includeProfiles) {
8281                includedUsers = getProfileIdsLocked(userId);
8282            } else {
8283                includedUsers = new HashSet<Integer>();
8284            }
8285            includedUsers.add(Integer.valueOf(userId));
8286
8287            for (int i=0; i<N && maxNum > 0; i++) {
8288                TaskRecord tr = mRecentTasks.get(i);
8289                // Only add calling user or related users recent tasks
8290                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8291                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8292                    continue;
8293                }
8294
8295                // Return the entry if desired by the caller.  We always return
8296                // the first entry, because callers always expect this to be the
8297                // foreground app.  We may filter others if the caller has
8298                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8299                // we should exclude the entry.
8300
8301                if (i == 0
8302                        || withExcluded
8303                        || (tr.intent == null)
8304                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8305                                == 0)) {
8306                    if (!allowed) {
8307                        // If the caller doesn't have the GET_TASKS permission, then only
8308                        // allow them to see a small subset of tasks -- their own and home.
8309                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8310                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8311                            continue;
8312                        }
8313                    }
8314                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8315                        if (tr.stack != null && tr.stack.isHomeStack()) {
8316                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8317                            continue;
8318                        }
8319                    }
8320                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8321                        // Don't include auto remove tasks that are finished or finishing.
8322                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8323                                + tr);
8324                        continue;
8325                    }
8326                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8327                            && !tr.isAvailable) {
8328                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8329                        continue;
8330                    }
8331
8332                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8333                    if (!detailed) {
8334                        rti.baseIntent.replaceExtras((Bundle)null);
8335                    }
8336
8337                    res.add(rti);
8338                    maxNum--;
8339                }
8340            }
8341            return res;
8342        }
8343    }
8344
8345    private TaskRecord recentTaskForIdLocked(int id) {
8346        final int N = mRecentTasks.size();
8347            for (int i=0; i<N; i++) {
8348                TaskRecord tr = mRecentTasks.get(i);
8349                if (tr.taskId == id) {
8350                    return tr;
8351                }
8352            }
8353            return null;
8354    }
8355
8356    @Override
8357    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8358        synchronized (this) {
8359            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8360                    "getTaskThumbnail()");
8361            TaskRecord tr = recentTaskForIdLocked(id);
8362            if (tr != null) {
8363                return tr.getTaskThumbnailLocked();
8364            }
8365        }
8366        return null;
8367    }
8368
8369    @Override
8370    public int addAppTask(IBinder activityToken, Intent intent,
8371            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8372        final int callingUid = Binder.getCallingUid();
8373        final long callingIdent = Binder.clearCallingIdentity();
8374
8375        try {
8376            synchronized (this) {
8377                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8378                if (r == null) {
8379                    throw new IllegalArgumentException("Activity does not exist; token="
8380                            + activityToken);
8381                }
8382                ComponentName comp = intent.getComponent();
8383                if (comp == null) {
8384                    throw new IllegalArgumentException("Intent " + intent
8385                            + " must specify explicit component");
8386                }
8387                if (thumbnail.getWidth() != mThumbnailWidth
8388                        || thumbnail.getHeight() != mThumbnailHeight) {
8389                    throw new IllegalArgumentException("Bad thumbnail size: got "
8390                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8391                            + mThumbnailWidth + "x" + mThumbnailHeight);
8392                }
8393                if (intent.getSelector() != null) {
8394                    intent.setSelector(null);
8395                }
8396                if (intent.getSourceBounds() != null) {
8397                    intent.setSourceBounds(null);
8398                }
8399                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8400                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8401                        // The caller has added this as an auto-remove task...  that makes no
8402                        // sense, so turn off auto-remove.
8403                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8404                    }
8405                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8406                    // Must be a new task.
8407                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8408                }
8409                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8410                    mLastAddedTaskActivity = null;
8411                }
8412                ActivityInfo ainfo = mLastAddedTaskActivity;
8413                if (ainfo == null) {
8414                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8415                            comp, 0, UserHandle.getUserId(callingUid));
8416                    if (ainfo.applicationInfo.uid != callingUid) {
8417                        throw new SecurityException(
8418                                "Can't add task for another application: target uid="
8419                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8420                    }
8421                }
8422
8423                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8424                        intent, description);
8425
8426                int trimIdx = trimRecentsForTask(task, false);
8427                if (trimIdx >= 0) {
8428                    // If this would have caused a trim, then we'll abort because that
8429                    // means it would be added at the end of the list but then just removed.
8430                    return -1;
8431                }
8432
8433                final int N = mRecentTasks.size();
8434                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8435                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8436                    tr.removedFromRecents(mTaskPersister);
8437                }
8438
8439                task.inRecents = true;
8440                mRecentTasks.add(task);
8441                r.task.stack.addTask(task, false, false);
8442
8443                task.setLastThumbnail(thumbnail);
8444                task.freeLastThumbnail();
8445
8446                return task.taskId;
8447            }
8448        } finally {
8449            Binder.restoreCallingIdentity(callingIdent);
8450        }
8451    }
8452
8453    @Override
8454    public Point getAppTaskThumbnailSize() {
8455        synchronized (this) {
8456            return new Point(mThumbnailWidth,  mThumbnailHeight);
8457        }
8458    }
8459
8460    @Override
8461    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8462        synchronized (this) {
8463            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8464            if (r != null) {
8465                r.setTaskDescription(td);
8466                r.task.updateTaskDescription();
8467            }
8468        }
8469    }
8470
8471    @Override
8472    public Bitmap getTaskDescriptionIcon(String filename) {
8473        if (!FileUtils.isValidExtFilename(filename)
8474                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8475            throw new IllegalArgumentException("Bad filename: " + filename);
8476        }
8477        return mTaskPersister.getTaskDescriptionIcon(filename);
8478    }
8479
8480    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8481        mRecentTasks.remove(tr);
8482        tr.removedFromRecents(mTaskPersister);
8483        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8484        Intent baseIntent = new Intent(
8485                tr.intent != null ? tr.intent : tr.affinityIntent);
8486        ComponentName component = baseIntent.getComponent();
8487        if (component == null) {
8488            Slog.w(TAG, "Now component for base intent of task: " + tr);
8489            return;
8490        }
8491
8492        // Find any running services associated with this app.
8493        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8494
8495        if (killProcesses) {
8496            // Find any running processes associated with this app.
8497            final String pkg = component.getPackageName();
8498            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8499            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8500            for (int i=0; i<pmap.size(); i++) {
8501                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8502                for (int j=0; j<uids.size(); j++) {
8503                    ProcessRecord proc = uids.valueAt(j);
8504                    if (proc.userId != tr.userId) {
8505                        continue;
8506                    }
8507                    if (!proc.pkgList.containsKey(pkg)) {
8508                        continue;
8509                    }
8510                    procs.add(proc);
8511                }
8512            }
8513
8514            // Kill the running processes.
8515            for (int i=0; i<procs.size(); i++) {
8516                ProcessRecord pr = procs.get(i);
8517                if (pr == mHomeProcess) {
8518                    // Don't kill the home process along with tasks from the same package.
8519                    continue;
8520                }
8521                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8522                    pr.kill("remove task", true);
8523                } else {
8524                    pr.waitingToKill = "remove task";
8525                }
8526            }
8527        }
8528    }
8529
8530    /**
8531     * Removes the task with the specified task id.
8532     *
8533     * @param taskId Identifier of the task to be removed.
8534     * @param flags Additional operational flags.  May be 0 or
8535     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8536     * @return Returns true if the given task was found and removed.
8537     */
8538    private boolean removeTaskByIdLocked(int taskId, int flags) {
8539        TaskRecord tr = recentTaskForIdLocked(taskId);
8540        if (tr != null) {
8541            tr.removeTaskActivitiesLocked();
8542            cleanUpRemovedTaskLocked(tr, flags);
8543            if (tr.isPersistable) {
8544                notifyTaskPersisterLocked(null, true);
8545            }
8546            return true;
8547        }
8548        return false;
8549    }
8550
8551    @Override
8552    public boolean removeTask(int taskId, int flags) {
8553        synchronized (this) {
8554            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8555                    "removeTask()");
8556            long ident = Binder.clearCallingIdentity();
8557            try {
8558                return removeTaskByIdLocked(taskId, flags);
8559            } finally {
8560                Binder.restoreCallingIdentity(ident);
8561            }
8562        }
8563    }
8564
8565    /**
8566     * TODO: Add mController hook
8567     */
8568    @Override
8569    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8570        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8571                "moveTaskToFront()");
8572
8573        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8574        synchronized(this) {
8575            moveTaskToFrontLocked(taskId, flags, options);
8576        }
8577    }
8578
8579    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8580        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8581                Binder.getCallingUid(), -1, -1, "Task to front")) {
8582            ActivityOptions.abort(options);
8583            return;
8584        }
8585        final long origId = Binder.clearCallingIdentity();
8586        try {
8587            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8588            if (task == null) {
8589                return;
8590            }
8591            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8592                mStackSupervisor.showLockTaskToast();
8593                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8594                return;
8595            }
8596            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8597            if (prev != null && prev.isRecentsActivity()) {
8598                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8599            }
8600            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8601        } finally {
8602            Binder.restoreCallingIdentity(origId);
8603        }
8604        ActivityOptions.abort(options);
8605    }
8606
8607    @Override
8608    public void moveTaskToBack(int taskId) {
8609        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8610                "moveTaskToBack()");
8611
8612        synchronized(this) {
8613            TaskRecord tr = recentTaskForIdLocked(taskId);
8614            if (tr != null) {
8615                if (tr == mStackSupervisor.mLockTaskModeTask) {
8616                    mStackSupervisor.showLockTaskToast();
8617                    return;
8618                }
8619                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8620                ActivityStack stack = tr.stack;
8621                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8622                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8623                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8624                        return;
8625                    }
8626                }
8627                final long origId = Binder.clearCallingIdentity();
8628                try {
8629                    stack.moveTaskToBackLocked(taskId, null);
8630                } finally {
8631                    Binder.restoreCallingIdentity(origId);
8632                }
8633            }
8634        }
8635    }
8636
8637    /**
8638     * Moves an activity, and all of the other activities within the same task, to the bottom
8639     * of the history stack.  The activity's order within the task is unchanged.
8640     *
8641     * @param token A reference to the activity we wish to move
8642     * @param nonRoot If false then this only works if the activity is the root
8643     *                of a task; if true it will work for any activity in a task.
8644     * @return Returns true if the move completed, false if not.
8645     */
8646    @Override
8647    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8648        enforceNotIsolatedCaller("moveActivityTaskToBack");
8649        synchronized(this) {
8650            final long origId = Binder.clearCallingIdentity();
8651            try {
8652                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8653                if (taskId >= 0) {
8654                    if ((mStackSupervisor.mLockTaskModeTask != null)
8655                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8656                        mStackSupervisor.showLockTaskToast();
8657                        return false;
8658                    }
8659                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8660                }
8661            } finally {
8662                Binder.restoreCallingIdentity(origId);
8663            }
8664        }
8665        return false;
8666    }
8667
8668    @Override
8669    public void moveTaskBackwards(int task) {
8670        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8671                "moveTaskBackwards()");
8672
8673        synchronized(this) {
8674            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8675                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8676                return;
8677            }
8678            final long origId = Binder.clearCallingIdentity();
8679            moveTaskBackwardsLocked(task);
8680            Binder.restoreCallingIdentity(origId);
8681        }
8682    }
8683
8684    private final void moveTaskBackwardsLocked(int task) {
8685        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8686    }
8687
8688    @Override
8689    public IBinder getHomeActivityToken() throws RemoteException {
8690        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8691                "getHomeActivityToken()");
8692        synchronized (this) {
8693            return mStackSupervisor.getHomeActivityToken();
8694        }
8695    }
8696
8697    @Override
8698    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8699            IActivityContainerCallback callback) throws RemoteException {
8700        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701                "createActivityContainer()");
8702        synchronized (this) {
8703            if (parentActivityToken == null) {
8704                throw new IllegalArgumentException("parent token must not be null");
8705            }
8706            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8707            if (r == null) {
8708                return null;
8709            }
8710            if (callback == null) {
8711                throw new IllegalArgumentException("callback must not be null");
8712            }
8713            return mStackSupervisor.createActivityContainer(r, callback);
8714        }
8715    }
8716
8717    @Override
8718    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8719        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8720                "deleteActivityContainer()");
8721        synchronized (this) {
8722            mStackSupervisor.deleteActivityContainer(container);
8723        }
8724    }
8725
8726    @Override
8727    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8728            throws RemoteException {
8729        synchronized (this) {
8730            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8731            if (stack != null) {
8732                return stack.mActivityContainer;
8733            }
8734            return null;
8735        }
8736    }
8737
8738    @Override
8739    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8740        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8741                "moveTaskToStack()");
8742        if (stackId == HOME_STACK_ID) {
8743            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8744                    new RuntimeException("here").fillInStackTrace());
8745        }
8746        synchronized (this) {
8747            long ident = Binder.clearCallingIdentity();
8748            try {
8749                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8750                        + stackId + " toTop=" + toTop);
8751                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8752            } finally {
8753                Binder.restoreCallingIdentity(ident);
8754            }
8755        }
8756    }
8757
8758    @Override
8759    public void resizeStack(int stackBoxId, Rect bounds) {
8760        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8761                "resizeStackBox()");
8762        long ident = Binder.clearCallingIdentity();
8763        try {
8764            mWindowManager.resizeStack(stackBoxId, bounds);
8765        } finally {
8766            Binder.restoreCallingIdentity(ident);
8767        }
8768    }
8769
8770    @Override
8771    public List<StackInfo> getAllStackInfos() {
8772        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8773                "getAllStackInfos()");
8774        long ident = Binder.clearCallingIdentity();
8775        try {
8776            synchronized (this) {
8777                return mStackSupervisor.getAllStackInfosLocked();
8778            }
8779        } finally {
8780            Binder.restoreCallingIdentity(ident);
8781        }
8782    }
8783
8784    @Override
8785    public StackInfo getStackInfo(int stackId) {
8786        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8787                "getStackInfo()");
8788        long ident = Binder.clearCallingIdentity();
8789        try {
8790            synchronized (this) {
8791                return mStackSupervisor.getStackInfoLocked(stackId);
8792            }
8793        } finally {
8794            Binder.restoreCallingIdentity(ident);
8795        }
8796    }
8797
8798    @Override
8799    public boolean isInHomeStack(int taskId) {
8800        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8801                "getStackInfo()");
8802        long ident = Binder.clearCallingIdentity();
8803        try {
8804            synchronized (this) {
8805                TaskRecord tr = recentTaskForIdLocked(taskId);
8806                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8807            }
8808        } finally {
8809            Binder.restoreCallingIdentity(ident);
8810        }
8811    }
8812
8813    @Override
8814    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8815        synchronized(this) {
8816            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8817        }
8818    }
8819
8820    private boolean isLockTaskAuthorized(String pkg) {
8821        final DevicePolicyManager dpm = (DevicePolicyManager)
8822                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8823        try {
8824            int uid = mContext.getPackageManager().getPackageUid(pkg,
8825                    Binder.getCallingUserHandle().getIdentifier());
8826            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8827        } catch (NameNotFoundException e) {
8828            return false;
8829        }
8830    }
8831
8832    void startLockTaskMode(TaskRecord task) {
8833        final String pkg;
8834        synchronized (this) {
8835            pkg = task.intent.getComponent().getPackageName();
8836        }
8837        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8838        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8839            final TaskRecord taskRecord = task;
8840            mHandler.post(new Runnable() {
8841                @Override
8842                public void run() {
8843                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8844                }
8845            });
8846            return;
8847        }
8848        long ident = Binder.clearCallingIdentity();
8849        try {
8850            synchronized (this) {
8851                // Since we lost lock on task, make sure it is still there.
8852                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8853                if (task != null) {
8854                    if (!isSystemInitiated
8855                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8856                        throw new IllegalArgumentException("Invalid task, not in foreground");
8857                    }
8858                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8859                }
8860            }
8861        } finally {
8862            Binder.restoreCallingIdentity(ident);
8863        }
8864    }
8865
8866    @Override
8867    public void startLockTaskMode(int taskId) {
8868        final TaskRecord task;
8869        long ident = Binder.clearCallingIdentity();
8870        try {
8871            synchronized (this) {
8872                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8873            }
8874        } finally {
8875            Binder.restoreCallingIdentity(ident);
8876        }
8877        if (task != null) {
8878            startLockTaskMode(task);
8879        }
8880    }
8881
8882    @Override
8883    public void startLockTaskMode(IBinder token) {
8884        final TaskRecord task;
8885        long ident = Binder.clearCallingIdentity();
8886        try {
8887            synchronized (this) {
8888                final ActivityRecord r = ActivityRecord.forToken(token);
8889                if (r == null) {
8890                    return;
8891                }
8892                task = r.task;
8893            }
8894        } finally {
8895            Binder.restoreCallingIdentity(ident);
8896        }
8897        if (task != null) {
8898            startLockTaskMode(task);
8899        }
8900    }
8901
8902    @Override
8903    public void startLockTaskModeOnCurrent() throws RemoteException {
8904        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8905                "startLockTaskModeOnCurrent");
8906        ActivityRecord r = null;
8907        synchronized (this) {
8908            r = mStackSupervisor.topRunningActivityLocked();
8909        }
8910        startLockTaskMode(r.task);
8911    }
8912
8913    @Override
8914    public void stopLockTaskMode() {
8915        // Verify that the user matches the package of the intent for the TaskRecord
8916        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8917        // and stopLockTaskMode.
8918        final int callingUid = Binder.getCallingUid();
8919        if (callingUid != Process.SYSTEM_UID) {
8920            try {
8921                String pkg =
8922                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8923                int uid = mContext.getPackageManager().getPackageUid(pkg,
8924                        Binder.getCallingUserHandle().getIdentifier());
8925                if (uid != callingUid) {
8926                    throw new SecurityException("Invalid uid, expected " + uid);
8927                }
8928            } catch (NameNotFoundException e) {
8929                Log.d(TAG, "stopLockTaskMode " + e);
8930                return;
8931            }
8932        }
8933        long ident = Binder.clearCallingIdentity();
8934        try {
8935            Log.d(TAG, "stopLockTaskMode");
8936            // Stop lock task
8937            synchronized (this) {
8938                mStackSupervisor.setLockTaskModeLocked(null, false);
8939            }
8940        } finally {
8941            Binder.restoreCallingIdentity(ident);
8942        }
8943    }
8944
8945    @Override
8946    public void stopLockTaskModeOnCurrent() throws RemoteException {
8947        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8948                "stopLockTaskModeOnCurrent");
8949        long ident = Binder.clearCallingIdentity();
8950        try {
8951            stopLockTaskMode();
8952        } finally {
8953            Binder.restoreCallingIdentity(ident);
8954        }
8955    }
8956
8957    @Override
8958    public boolean isInLockTaskMode() {
8959        synchronized (this) {
8960            return mStackSupervisor.isInLockTaskMode();
8961        }
8962    }
8963
8964    // =========================================================
8965    // CONTENT PROVIDERS
8966    // =========================================================
8967
8968    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8969        List<ProviderInfo> providers = null;
8970        try {
8971            providers = AppGlobals.getPackageManager().
8972                queryContentProviders(app.processName, app.uid,
8973                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8974        } catch (RemoteException ex) {
8975        }
8976        if (DEBUG_MU)
8977            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8978        int userId = app.userId;
8979        if (providers != null) {
8980            int N = providers.size();
8981            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8982            for (int i=0; i<N; i++) {
8983                ProviderInfo cpi =
8984                    (ProviderInfo)providers.get(i);
8985                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8986                        cpi.name, cpi.flags);
8987                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8988                    // This is a singleton provider, but a user besides the
8989                    // default user is asking to initialize a process it runs
8990                    // in...  well, no, it doesn't actually run in this process,
8991                    // it runs in the process of the default user.  Get rid of it.
8992                    providers.remove(i);
8993                    N--;
8994                    i--;
8995                    continue;
8996                }
8997
8998                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8999                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9000                if (cpr == null) {
9001                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9002                    mProviderMap.putProviderByClass(comp, cpr);
9003                }
9004                if (DEBUG_MU)
9005                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9006                app.pubProviders.put(cpi.name, cpr);
9007                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9008                    // Don't add this if it is a platform component that is marked
9009                    // to run in multiple processes, because this is actually
9010                    // part of the framework so doesn't make sense to track as a
9011                    // separate apk in the process.
9012                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9013                            mProcessStats);
9014                }
9015                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9016            }
9017        }
9018        return providers;
9019    }
9020
9021    /**
9022     * Check if {@link ProcessRecord} has a possible chance at accessing the
9023     * given {@link ProviderInfo}. Final permission checking is always done
9024     * in {@link ContentProvider}.
9025     */
9026    private final String checkContentProviderPermissionLocked(
9027            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9028        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9029        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9030        boolean checkedGrants = false;
9031        if (checkUser) {
9032            // Looking for cross-user grants before enforcing the typical cross-users permissions
9033            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9034            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9035                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9036                    return null;
9037                }
9038                checkedGrants = true;
9039            }
9040            userId = handleIncomingUser(callingPid, callingUid, userId,
9041                    false, ALLOW_NON_FULL,
9042                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9043            if (userId != tmpTargetUserId) {
9044                // When we actually went to determine the final targer user ID, this ended
9045                // up different than our initial check for the authority.  This is because
9046                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9047                // SELF.  So we need to re-check the grants again.
9048                checkedGrants = false;
9049            }
9050        }
9051        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9052                cpi.applicationInfo.uid, cpi.exported)
9053                == PackageManager.PERMISSION_GRANTED) {
9054            return null;
9055        }
9056        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9057                cpi.applicationInfo.uid, cpi.exported)
9058                == PackageManager.PERMISSION_GRANTED) {
9059            return null;
9060        }
9061
9062        PathPermission[] pps = cpi.pathPermissions;
9063        if (pps != null) {
9064            int i = pps.length;
9065            while (i > 0) {
9066                i--;
9067                PathPermission pp = pps[i];
9068                String pprperm = pp.getReadPermission();
9069                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9070                        cpi.applicationInfo.uid, cpi.exported)
9071                        == PackageManager.PERMISSION_GRANTED) {
9072                    return null;
9073                }
9074                String ppwperm = pp.getWritePermission();
9075                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9076                        cpi.applicationInfo.uid, cpi.exported)
9077                        == PackageManager.PERMISSION_GRANTED) {
9078                    return null;
9079                }
9080            }
9081        }
9082        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9083            return null;
9084        }
9085
9086        String msg;
9087        if (!cpi.exported) {
9088            msg = "Permission Denial: opening provider " + cpi.name
9089                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9090                    + ", uid=" + callingUid + ") that is not exported from uid "
9091                    + cpi.applicationInfo.uid;
9092        } else {
9093            msg = "Permission Denial: opening provider " + cpi.name
9094                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9095                    + ", uid=" + callingUid + ") requires "
9096                    + cpi.readPermission + " or " + cpi.writePermission;
9097        }
9098        Slog.w(TAG, msg);
9099        return msg;
9100    }
9101
9102    /**
9103     * Returns if the ContentProvider has granted a uri to callingUid
9104     */
9105    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9106        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9107        if (perms != null) {
9108            for (int i=perms.size()-1; i>=0; i--) {
9109                GrantUri grantUri = perms.keyAt(i);
9110                if (grantUri.sourceUserId == userId || !checkUser) {
9111                    if (matchesProvider(grantUri.uri, cpi)) {
9112                        return true;
9113                    }
9114                }
9115            }
9116        }
9117        return false;
9118    }
9119
9120    /**
9121     * Returns true if the uri authority is one of the authorities specified in the provider.
9122     */
9123    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9124        String uriAuth = uri.getAuthority();
9125        String cpiAuth = cpi.authority;
9126        if (cpiAuth.indexOf(';') == -1) {
9127            return cpiAuth.equals(uriAuth);
9128        }
9129        String[] cpiAuths = cpiAuth.split(";");
9130        int length = cpiAuths.length;
9131        for (int i = 0; i < length; i++) {
9132            if (cpiAuths[i].equals(uriAuth)) return true;
9133        }
9134        return false;
9135    }
9136
9137    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9138            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9139        if (r != null) {
9140            for (int i=0; i<r.conProviders.size(); i++) {
9141                ContentProviderConnection conn = r.conProviders.get(i);
9142                if (conn.provider == cpr) {
9143                    if (DEBUG_PROVIDER) Slog.v(TAG,
9144                            "Adding provider requested by "
9145                            + r.processName + " from process "
9146                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9147                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9148                    if (stable) {
9149                        conn.stableCount++;
9150                        conn.numStableIncs++;
9151                    } else {
9152                        conn.unstableCount++;
9153                        conn.numUnstableIncs++;
9154                    }
9155                    return conn;
9156                }
9157            }
9158            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9159            if (stable) {
9160                conn.stableCount = 1;
9161                conn.numStableIncs = 1;
9162            } else {
9163                conn.unstableCount = 1;
9164                conn.numUnstableIncs = 1;
9165            }
9166            cpr.connections.add(conn);
9167            r.conProviders.add(conn);
9168            return conn;
9169        }
9170        cpr.addExternalProcessHandleLocked(externalProcessToken);
9171        return null;
9172    }
9173
9174    boolean decProviderCountLocked(ContentProviderConnection conn,
9175            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9176        if (conn != null) {
9177            cpr = conn.provider;
9178            if (DEBUG_PROVIDER) Slog.v(TAG,
9179                    "Removing provider requested by "
9180                    + conn.client.processName + " from process "
9181                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9182                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9183            if (stable) {
9184                conn.stableCount--;
9185            } else {
9186                conn.unstableCount--;
9187            }
9188            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9189                cpr.connections.remove(conn);
9190                conn.client.conProviders.remove(conn);
9191                return true;
9192            }
9193            return false;
9194        }
9195        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9196        return false;
9197    }
9198
9199    private void checkTime(long startTime, String where) {
9200        long now = SystemClock.elapsedRealtime();
9201        if ((now-startTime) > 1000) {
9202            // If we are taking more than a second, log about it.
9203            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9204        }
9205    }
9206
9207    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9208            String name, IBinder token, boolean stable, int userId) {
9209        ContentProviderRecord cpr;
9210        ContentProviderConnection conn = null;
9211        ProviderInfo cpi = null;
9212
9213        synchronized(this) {
9214            long startTime = SystemClock.elapsedRealtime();
9215
9216            ProcessRecord r = null;
9217            if (caller != null) {
9218                r = getRecordForAppLocked(caller);
9219                if (r == null) {
9220                    throw new SecurityException(
9221                            "Unable to find app for caller " + caller
9222                          + " (pid=" + Binder.getCallingPid()
9223                          + ") when getting content provider " + name);
9224                }
9225            }
9226
9227            boolean checkCrossUser = true;
9228
9229            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9230
9231            // First check if this content provider has been published...
9232            cpr = mProviderMap.getProviderByName(name, userId);
9233            // If that didn't work, check if it exists for user 0 and then
9234            // verify that it's a singleton provider before using it.
9235            if (cpr == null && userId != UserHandle.USER_OWNER) {
9236                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9237                if (cpr != null) {
9238                    cpi = cpr.info;
9239                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9240                            cpi.name, cpi.flags)
9241                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9242                        userId = UserHandle.USER_OWNER;
9243                        checkCrossUser = false;
9244                    } else {
9245                        cpr = null;
9246                        cpi = null;
9247                    }
9248                }
9249            }
9250
9251            boolean providerRunning = cpr != null;
9252            if (providerRunning) {
9253                cpi = cpr.info;
9254                String msg;
9255                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9256                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9257                        != null) {
9258                    throw new SecurityException(msg);
9259                }
9260                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9261
9262                if (r != null && cpr.canRunHere(r)) {
9263                    // This provider has been published or is in the process
9264                    // of being published...  but it is also allowed to run
9265                    // in the caller's process, so don't make a connection
9266                    // and just let the caller instantiate its own instance.
9267                    ContentProviderHolder holder = cpr.newHolder(null);
9268                    // don't give caller the provider object, it needs
9269                    // to make its own.
9270                    holder.provider = null;
9271                    return holder;
9272                }
9273
9274                final long origId = Binder.clearCallingIdentity();
9275
9276                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9277
9278                // In this case the provider instance already exists, so we can
9279                // return it right away.
9280                conn = incProviderCountLocked(r, cpr, token, stable);
9281                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9282                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9283                        // If this is a perceptible app accessing the provider,
9284                        // make sure to count it as being accessed and thus
9285                        // back up on the LRU list.  This is good because
9286                        // content providers are often expensive to start.
9287                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9288                        updateLruProcessLocked(cpr.proc, false, null);
9289                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9290                    }
9291                }
9292
9293                if (cpr.proc != null) {
9294                    if (false) {
9295                        if (cpr.name.flattenToShortString().equals(
9296                                "com.android.providers.calendar/.CalendarProvider2")) {
9297                            Slog.v(TAG, "****************** KILLING "
9298                                + cpr.name.flattenToShortString());
9299                            Process.killProcess(cpr.proc.pid);
9300                        }
9301                    }
9302                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9303                    boolean success = updateOomAdjLocked(cpr.proc);
9304                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9305                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9306                    // NOTE: there is still a race here where a signal could be
9307                    // pending on the process even though we managed to update its
9308                    // adj level.  Not sure what to do about this, but at least
9309                    // the race is now smaller.
9310                    if (!success) {
9311                        // Uh oh...  it looks like the provider's process
9312                        // has been killed on us.  We need to wait for a new
9313                        // process to be started, and make sure its death
9314                        // doesn't kill our process.
9315                        Slog.i(TAG,
9316                                "Existing provider " + cpr.name.flattenToShortString()
9317                                + " is crashing; detaching " + r);
9318                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9319                        checkTime(startTime, "getContentProviderImpl: before appDied");
9320                        appDiedLocked(cpr.proc);
9321                        checkTime(startTime, "getContentProviderImpl: after appDied");
9322                        if (!lastRef) {
9323                            // This wasn't the last ref our process had on
9324                            // the provider...  we have now been killed, bail.
9325                            return null;
9326                        }
9327                        providerRunning = false;
9328                        conn = null;
9329                    }
9330                }
9331
9332                Binder.restoreCallingIdentity(origId);
9333            }
9334
9335            boolean singleton;
9336            if (!providerRunning) {
9337                try {
9338                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9339                    cpi = AppGlobals.getPackageManager().
9340                        resolveContentProvider(name,
9341                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9342                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9343                } catch (RemoteException ex) {
9344                }
9345                if (cpi == null) {
9346                    return null;
9347                }
9348                // If the provider is a singleton AND
9349                // (it's a call within the same user || the provider is a
9350                // privileged app)
9351                // Then allow connecting to the singleton provider
9352                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9353                        cpi.name, cpi.flags)
9354                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9355                if (singleton) {
9356                    userId = UserHandle.USER_OWNER;
9357                }
9358                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9359                checkTime(startTime, "getContentProviderImpl: got app info for user");
9360
9361                String msg;
9362                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9363                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9364                        != null) {
9365                    throw new SecurityException(msg);
9366                }
9367                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9368
9369                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9370                        && !cpi.processName.equals("system")) {
9371                    // If this content provider does not run in the system
9372                    // process, and the system is not yet ready to run other
9373                    // processes, then fail fast instead of hanging.
9374                    throw new IllegalArgumentException(
9375                            "Attempt to launch content provider before system ready");
9376                }
9377
9378                // Make sure that the user who owns this provider is started.  If not,
9379                // we don't want to allow it to run.
9380                if (mStartedUsers.get(userId) == null) {
9381                    Slog.w(TAG, "Unable to launch app "
9382                            + cpi.applicationInfo.packageName + "/"
9383                            + cpi.applicationInfo.uid + " for provider "
9384                            + name + ": user " + userId + " is stopped");
9385                    return null;
9386                }
9387
9388                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9389                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9390                cpr = mProviderMap.getProviderByClass(comp, userId);
9391                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9392                final boolean firstClass = cpr == null;
9393                if (firstClass) {
9394                    final long ident = Binder.clearCallingIdentity();
9395                    try {
9396                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9397                        ApplicationInfo ai =
9398                            AppGlobals.getPackageManager().
9399                                getApplicationInfo(
9400                                        cpi.applicationInfo.packageName,
9401                                        STOCK_PM_FLAGS, userId);
9402                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9403                        if (ai == null) {
9404                            Slog.w(TAG, "No package info for content provider "
9405                                    + cpi.name);
9406                            return null;
9407                        }
9408                        ai = getAppInfoForUser(ai, userId);
9409                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9410                    } catch (RemoteException ex) {
9411                        // pm is in same process, this will never happen.
9412                    } finally {
9413                        Binder.restoreCallingIdentity(ident);
9414                    }
9415                }
9416
9417                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9418
9419                if (r != null && cpr.canRunHere(r)) {
9420                    // If this is a multiprocess provider, then just return its
9421                    // info and allow the caller to instantiate it.  Only do
9422                    // this if the provider is the same user as the caller's
9423                    // process, or can run as root (so can be in any process).
9424                    return cpr.newHolder(null);
9425                }
9426
9427                if (DEBUG_PROVIDER) {
9428                    RuntimeException e = new RuntimeException("here");
9429                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9430                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9431                }
9432
9433                // This is single process, and our app is now connecting to it.
9434                // See if we are already in the process of launching this
9435                // provider.
9436                final int N = mLaunchingProviders.size();
9437                int i;
9438                for (i=0; i<N; i++) {
9439                    if (mLaunchingProviders.get(i) == cpr) {
9440                        break;
9441                    }
9442                }
9443
9444                // If the provider is not already being launched, then get it
9445                // started.
9446                if (i >= N) {
9447                    final long origId = Binder.clearCallingIdentity();
9448
9449                    try {
9450                        // Content provider is now in use, its package can't be stopped.
9451                        try {
9452                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9453                            AppGlobals.getPackageManager().setPackageStoppedState(
9454                                    cpr.appInfo.packageName, false, userId);
9455                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9456                        } catch (RemoteException e) {
9457                        } catch (IllegalArgumentException e) {
9458                            Slog.w(TAG, "Failed trying to unstop package "
9459                                    + cpr.appInfo.packageName + ": " + e);
9460                        }
9461
9462                        // Use existing process if already started
9463                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9464                        ProcessRecord proc = getProcessRecordLocked(
9465                                cpi.processName, cpr.appInfo.uid, false);
9466                        if (proc != null && proc.thread != null) {
9467                            if (DEBUG_PROVIDER) {
9468                                Slog.d(TAG, "Installing in existing process " + proc);
9469                            }
9470                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9471                            proc.pubProviders.put(cpi.name, cpr);
9472                            try {
9473                                proc.thread.scheduleInstallProvider(cpi);
9474                            } catch (RemoteException e) {
9475                            }
9476                        } else {
9477                            checkTime(startTime, "getContentProviderImpl: before start process");
9478                            proc = startProcessLocked(cpi.processName,
9479                                    cpr.appInfo, false, 0, "content provider",
9480                                    new ComponentName(cpi.applicationInfo.packageName,
9481                                            cpi.name), false, false, false);
9482                            checkTime(startTime, "getContentProviderImpl: after start process");
9483                            if (proc == null) {
9484                                Slog.w(TAG, "Unable to launch app "
9485                                        + cpi.applicationInfo.packageName + "/"
9486                                        + cpi.applicationInfo.uid + " for provider "
9487                                        + name + ": process is bad");
9488                                return null;
9489                            }
9490                        }
9491                        cpr.launchingApp = proc;
9492                        mLaunchingProviders.add(cpr);
9493                    } finally {
9494                        Binder.restoreCallingIdentity(origId);
9495                    }
9496                }
9497
9498                checkTime(startTime, "getContentProviderImpl: updating data structures");
9499
9500                // Make sure the provider is published (the same provider class
9501                // may be published under multiple names).
9502                if (firstClass) {
9503                    mProviderMap.putProviderByClass(comp, cpr);
9504                }
9505
9506                mProviderMap.putProviderByName(name, cpr);
9507                conn = incProviderCountLocked(r, cpr, token, stable);
9508                if (conn != null) {
9509                    conn.waiting = true;
9510                }
9511            }
9512            checkTime(startTime, "getContentProviderImpl: done!");
9513        }
9514
9515        // Wait for the provider to be published...
9516        synchronized (cpr) {
9517            while (cpr.provider == null) {
9518                if (cpr.launchingApp == null) {
9519                    Slog.w(TAG, "Unable to launch app "
9520                            + cpi.applicationInfo.packageName + "/"
9521                            + cpi.applicationInfo.uid + " for provider "
9522                            + name + ": launching app became null");
9523                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9524                            UserHandle.getUserId(cpi.applicationInfo.uid),
9525                            cpi.applicationInfo.packageName,
9526                            cpi.applicationInfo.uid, name);
9527                    return null;
9528                }
9529                try {
9530                    if (DEBUG_MU) {
9531                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9532                                + cpr.launchingApp);
9533                    }
9534                    if (conn != null) {
9535                        conn.waiting = true;
9536                    }
9537                    cpr.wait();
9538                } catch (InterruptedException ex) {
9539                } finally {
9540                    if (conn != null) {
9541                        conn.waiting = false;
9542                    }
9543                }
9544            }
9545        }
9546        return cpr != null ? cpr.newHolder(conn) : null;
9547    }
9548
9549    @Override
9550    public final ContentProviderHolder getContentProvider(
9551            IApplicationThread caller, String name, int userId, boolean stable) {
9552        enforceNotIsolatedCaller("getContentProvider");
9553        if (caller == null) {
9554            String msg = "null IApplicationThread when getting content provider "
9555                    + name;
9556            Slog.w(TAG, msg);
9557            throw new SecurityException(msg);
9558        }
9559        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9560        // with cross-user grant.
9561        return getContentProviderImpl(caller, name, null, stable, userId);
9562    }
9563
9564    public ContentProviderHolder getContentProviderExternal(
9565            String name, int userId, IBinder token) {
9566        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9567            "Do not have permission in call getContentProviderExternal()");
9568        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9569                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9570        return getContentProviderExternalUnchecked(name, token, userId);
9571    }
9572
9573    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9574            IBinder token, int userId) {
9575        return getContentProviderImpl(null, name, token, true, userId);
9576    }
9577
9578    /**
9579     * Drop a content provider from a ProcessRecord's bookkeeping
9580     */
9581    public void removeContentProvider(IBinder connection, boolean stable) {
9582        enforceNotIsolatedCaller("removeContentProvider");
9583        long ident = Binder.clearCallingIdentity();
9584        try {
9585            synchronized (this) {
9586                ContentProviderConnection conn;
9587                try {
9588                    conn = (ContentProviderConnection)connection;
9589                } catch (ClassCastException e) {
9590                    String msg ="removeContentProvider: " + connection
9591                            + " not a ContentProviderConnection";
9592                    Slog.w(TAG, msg);
9593                    throw new IllegalArgumentException(msg);
9594                }
9595                if (conn == null) {
9596                    throw new NullPointerException("connection is null");
9597                }
9598                if (decProviderCountLocked(conn, null, null, stable)) {
9599                    updateOomAdjLocked();
9600                }
9601            }
9602        } finally {
9603            Binder.restoreCallingIdentity(ident);
9604        }
9605    }
9606
9607    public void removeContentProviderExternal(String name, IBinder token) {
9608        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9609            "Do not have permission in call removeContentProviderExternal()");
9610        int userId = UserHandle.getCallingUserId();
9611        long ident = Binder.clearCallingIdentity();
9612        try {
9613            removeContentProviderExternalUnchecked(name, token, userId);
9614        } finally {
9615            Binder.restoreCallingIdentity(ident);
9616        }
9617    }
9618
9619    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9620        synchronized (this) {
9621            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9622            if(cpr == null) {
9623                //remove from mProvidersByClass
9624                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9625                return;
9626            }
9627
9628            //update content provider record entry info
9629            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9630            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9631            if (localCpr.hasExternalProcessHandles()) {
9632                if (localCpr.removeExternalProcessHandleLocked(token)) {
9633                    updateOomAdjLocked();
9634                } else {
9635                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9636                            + " with no external reference for token: "
9637                            + token + ".");
9638                }
9639            } else {
9640                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9641                        + " with no external references.");
9642            }
9643        }
9644    }
9645
9646    public final void publishContentProviders(IApplicationThread caller,
9647            List<ContentProviderHolder> providers) {
9648        if (providers == null) {
9649            return;
9650        }
9651
9652        enforceNotIsolatedCaller("publishContentProviders");
9653        synchronized (this) {
9654            final ProcessRecord r = getRecordForAppLocked(caller);
9655            if (DEBUG_MU)
9656                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9657            if (r == null) {
9658                throw new SecurityException(
9659                        "Unable to find app for caller " + caller
9660                      + " (pid=" + Binder.getCallingPid()
9661                      + ") when publishing content providers");
9662            }
9663
9664            final long origId = Binder.clearCallingIdentity();
9665
9666            final int N = providers.size();
9667            for (int i=0; i<N; i++) {
9668                ContentProviderHolder src = providers.get(i);
9669                if (src == null || src.info == null || src.provider == null) {
9670                    continue;
9671                }
9672                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9673                if (DEBUG_MU)
9674                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9675                if (dst != null) {
9676                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9677                    mProviderMap.putProviderByClass(comp, dst);
9678                    String names[] = dst.info.authority.split(";");
9679                    for (int j = 0; j < names.length; j++) {
9680                        mProviderMap.putProviderByName(names[j], dst);
9681                    }
9682
9683                    int NL = mLaunchingProviders.size();
9684                    int j;
9685                    for (j=0; j<NL; j++) {
9686                        if (mLaunchingProviders.get(j) == dst) {
9687                            mLaunchingProviders.remove(j);
9688                            j--;
9689                            NL--;
9690                        }
9691                    }
9692                    synchronized (dst) {
9693                        dst.provider = src.provider;
9694                        dst.proc = r;
9695                        dst.notifyAll();
9696                    }
9697                    updateOomAdjLocked(r);
9698                }
9699            }
9700
9701            Binder.restoreCallingIdentity(origId);
9702        }
9703    }
9704
9705    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9706        ContentProviderConnection conn;
9707        try {
9708            conn = (ContentProviderConnection)connection;
9709        } catch (ClassCastException e) {
9710            String msg ="refContentProvider: " + connection
9711                    + " not a ContentProviderConnection";
9712            Slog.w(TAG, msg);
9713            throw new IllegalArgumentException(msg);
9714        }
9715        if (conn == null) {
9716            throw new NullPointerException("connection is null");
9717        }
9718
9719        synchronized (this) {
9720            if (stable > 0) {
9721                conn.numStableIncs += stable;
9722            }
9723            stable = conn.stableCount + stable;
9724            if (stable < 0) {
9725                throw new IllegalStateException("stableCount < 0: " + stable);
9726            }
9727
9728            if (unstable > 0) {
9729                conn.numUnstableIncs += unstable;
9730            }
9731            unstable = conn.unstableCount + unstable;
9732            if (unstable < 0) {
9733                throw new IllegalStateException("unstableCount < 0: " + unstable);
9734            }
9735
9736            if ((stable+unstable) <= 0) {
9737                throw new IllegalStateException("ref counts can't go to zero here: stable="
9738                        + stable + " unstable=" + unstable);
9739            }
9740            conn.stableCount = stable;
9741            conn.unstableCount = unstable;
9742            return !conn.dead;
9743        }
9744    }
9745
9746    public void unstableProviderDied(IBinder connection) {
9747        ContentProviderConnection conn;
9748        try {
9749            conn = (ContentProviderConnection)connection;
9750        } catch (ClassCastException e) {
9751            String msg ="refContentProvider: " + connection
9752                    + " not a ContentProviderConnection";
9753            Slog.w(TAG, msg);
9754            throw new IllegalArgumentException(msg);
9755        }
9756        if (conn == null) {
9757            throw new NullPointerException("connection is null");
9758        }
9759
9760        // Safely retrieve the content provider associated with the connection.
9761        IContentProvider provider;
9762        synchronized (this) {
9763            provider = conn.provider.provider;
9764        }
9765
9766        if (provider == null) {
9767            // Um, yeah, we're way ahead of you.
9768            return;
9769        }
9770
9771        // Make sure the caller is being honest with us.
9772        if (provider.asBinder().pingBinder()) {
9773            // Er, no, still looks good to us.
9774            synchronized (this) {
9775                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9776                        + " says " + conn + " died, but we don't agree");
9777                return;
9778            }
9779        }
9780
9781        // Well look at that!  It's dead!
9782        synchronized (this) {
9783            if (conn.provider.provider != provider) {
9784                // But something changed...  good enough.
9785                return;
9786            }
9787
9788            ProcessRecord proc = conn.provider.proc;
9789            if (proc == null || proc.thread == null) {
9790                // Seems like the process is already cleaned up.
9791                return;
9792            }
9793
9794            // As far as we're concerned, this is just like receiving a
9795            // death notification...  just a bit prematurely.
9796            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9797                    + ") early provider death");
9798            final long ident = Binder.clearCallingIdentity();
9799            try {
9800                appDiedLocked(proc);
9801            } finally {
9802                Binder.restoreCallingIdentity(ident);
9803            }
9804        }
9805    }
9806
9807    @Override
9808    public void appNotRespondingViaProvider(IBinder connection) {
9809        enforceCallingPermission(
9810                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9811
9812        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9813        if (conn == null) {
9814            Slog.w(TAG, "ContentProviderConnection is null");
9815            return;
9816        }
9817
9818        final ProcessRecord host = conn.provider.proc;
9819        if (host == null) {
9820            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9821            return;
9822        }
9823
9824        final long token = Binder.clearCallingIdentity();
9825        try {
9826            appNotResponding(host, null, null, false, "ContentProvider not responding");
9827        } finally {
9828            Binder.restoreCallingIdentity(token);
9829        }
9830    }
9831
9832    public final void installSystemProviders() {
9833        List<ProviderInfo> providers;
9834        synchronized (this) {
9835            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9836            providers = generateApplicationProvidersLocked(app);
9837            if (providers != null) {
9838                for (int i=providers.size()-1; i>=0; i--) {
9839                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9840                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9841                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9842                                + ": not system .apk");
9843                        providers.remove(i);
9844                    }
9845                }
9846            }
9847        }
9848        if (providers != null) {
9849            mSystemThread.installSystemProviders(providers);
9850        }
9851
9852        mCoreSettingsObserver = new CoreSettingsObserver(this);
9853
9854        //mUsageStatsService.monitorPackages();
9855    }
9856
9857    /**
9858     * Allows apps to retrieve the MIME type of a URI.
9859     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9860     * users, then it does not need permission to access the ContentProvider.
9861     * Either, it needs cross-user uri grants.
9862     *
9863     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9864     *
9865     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9866     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9867     */
9868    public String getProviderMimeType(Uri uri, int userId) {
9869        enforceNotIsolatedCaller("getProviderMimeType");
9870        final String name = uri.getAuthority();
9871        int callingUid = Binder.getCallingUid();
9872        int callingPid = Binder.getCallingPid();
9873        long ident = 0;
9874        boolean clearedIdentity = false;
9875        userId = unsafeConvertIncomingUser(userId);
9876        if (canClearIdentity(callingPid, callingUid, userId)) {
9877            clearedIdentity = true;
9878            ident = Binder.clearCallingIdentity();
9879        }
9880        ContentProviderHolder holder = null;
9881        try {
9882            holder = getContentProviderExternalUnchecked(name, null, userId);
9883            if (holder != null) {
9884                return holder.provider.getType(uri);
9885            }
9886        } catch (RemoteException e) {
9887            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9888            return null;
9889        } finally {
9890            // We need to clear the identity to call removeContentProviderExternalUnchecked
9891            if (!clearedIdentity) {
9892                ident = Binder.clearCallingIdentity();
9893            }
9894            try {
9895                if (holder != null) {
9896                    removeContentProviderExternalUnchecked(name, null, userId);
9897                }
9898            } finally {
9899                Binder.restoreCallingIdentity(ident);
9900            }
9901        }
9902
9903        return null;
9904    }
9905
9906    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9907        if (UserHandle.getUserId(callingUid) == userId) {
9908            return true;
9909        }
9910        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9911                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9912                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9913                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9914                return true;
9915        }
9916        return false;
9917    }
9918
9919    // =========================================================
9920    // GLOBAL MANAGEMENT
9921    // =========================================================
9922
9923    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9924            boolean isolated, int isolatedUid) {
9925        String proc = customProcess != null ? customProcess : info.processName;
9926        BatteryStatsImpl.Uid.Proc ps = null;
9927        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9928        int uid = info.uid;
9929        if (isolated) {
9930            if (isolatedUid == 0) {
9931                int userId = UserHandle.getUserId(uid);
9932                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9933                while (true) {
9934                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9935                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9936                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9937                    }
9938                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9939                    mNextIsolatedProcessUid++;
9940                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9941                        // No process for this uid, use it.
9942                        break;
9943                    }
9944                    stepsLeft--;
9945                    if (stepsLeft <= 0) {
9946                        return null;
9947                    }
9948                }
9949            } else {
9950                // Special case for startIsolatedProcess (internal only), where
9951                // the uid of the isolated process is specified by the caller.
9952                uid = isolatedUid;
9953            }
9954        }
9955        return new ProcessRecord(stats, info, proc, uid);
9956    }
9957
9958    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9959            String abiOverride) {
9960        ProcessRecord app;
9961        if (!isolated) {
9962            app = getProcessRecordLocked(info.processName, info.uid, true);
9963        } else {
9964            app = null;
9965        }
9966
9967        if (app == null) {
9968            app = newProcessRecordLocked(info, null, isolated, 0);
9969            mProcessNames.put(info.processName, app.uid, app);
9970            if (isolated) {
9971                mIsolatedProcesses.put(app.uid, app);
9972            }
9973            updateLruProcessLocked(app, false, null);
9974            updateOomAdjLocked();
9975        }
9976
9977        // This package really, really can not be stopped.
9978        try {
9979            AppGlobals.getPackageManager().setPackageStoppedState(
9980                    info.packageName, false, UserHandle.getUserId(app.uid));
9981        } catch (RemoteException e) {
9982        } catch (IllegalArgumentException e) {
9983            Slog.w(TAG, "Failed trying to unstop package "
9984                    + info.packageName + ": " + e);
9985        }
9986
9987        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9988                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9989            app.persistent = true;
9990            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9991        }
9992        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9993            mPersistentStartingProcesses.add(app);
9994            startProcessLocked(app, "added application", app.processName, abiOverride,
9995                    null /* entryPoint */, null /* entryPointArgs */);
9996        }
9997
9998        return app;
9999    }
10000
10001    public void unhandledBack() {
10002        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10003                "unhandledBack()");
10004
10005        synchronized(this) {
10006            final long origId = Binder.clearCallingIdentity();
10007            try {
10008                getFocusedStack().unhandledBackLocked();
10009            } finally {
10010                Binder.restoreCallingIdentity(origId);
10011            }
10012        }
10013    }
10014
10015    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10016        enforceNotIsolatedCaller("openContentUri");
10017        final int userId = UserHandle.getCallingUserId();
10018        String name = uri.getAuthority();
10019        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10020        ParcelFileDescriptor pfd = null;
10021        if (cph != null) {
10022            // We record the binder invoker's uid in thread-local storage before
10023            // going to the content provider to open the file.  Later, in the code
10024            // that handles all permissions checks, we look for this uid and use
10025            // that rather than the Activity Manager's own uid.  The effect is that
10026            // we do the check against the caller's permissions even though it looks
10027            // to the content provider like the Activity Manager itself is making
10028            // the request.
10029            sCallerIdentity.set(new Identity(
10030                    Binder.getCallingPid(), Binder.getCallingUid()));
10031            try {
10032                pfd = cph.provider.openFile(null, uri, "r", null);
10033            } catch (FileNotFoundException e) {
10034                // do nothing; pfd will be returned null
10035            } finally {
10036                // Ensure that whatever happens, we clean up the identity state
10037                sCallerIdentity.remove();
10038            }
10039
10040            // We've got the fd now, so we're done with the provider.
10041            removeContentProviderExternalUnchecked(name, null, userId);
10042        } else {
10043            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10044        }
10045        return pfd;
10046    }
10047
10048    // Actually is sleeping or shutting down or whatever else in the future
10049    // is an inactive state.
10050    public boolean isSleepingOrShuttingDown() {
10051        return isSleeping() || mShuttingDown;
10052    }
10053
10054    public boolean isSleeping() {
10055        return mSleeping;
10056    }
10057
10058    void goingToSleep() {
10059        synchronized(this) {
10060            mWentToSleep = true;
10061            goToSleepIfNeededLocked();
10062        }
10063    }
10064
10065    void finishRunningVoiceLocked() {
10066        if (mRunningVoice) {
10067            mRunningVoice = false;
10068            goToSleepIfNeededLocked();
10069        }
10070    }
10071
10072    void goToSleepIfNeededLocked() {
10073        if (mWentToSleep && !mRunningVoice) {
10074            if (!mSleeping) {
10075                mSleeping = true;
10076                mStackSupervisor.goingToSleepLocked();
10077
10078                // Initialize the wake times of all processes.
10079                checkExcessivePowerUsageLocked(false);
10080                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10081                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10082                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10083            }
10084        }
10085    }
10086
10087    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10088        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10089            // Never persist the home stack.
10090            return;
10091        }
10092        mTaskPersister.wakeup(task, flush);
10093    }
10094
10095    @Override
10096    public boolean shutdown(int timeout) {
10097        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10098                != PackageManager.PERMISSION_GRANTED) {
10099            throw new SecurityException("Requires permission "
10100                    + android.Manifest.permission.SHUTDOWN);
10101        }
10102
10103        boolean timedout = false;
10104
10105        synchronized(this) {
10106            mShuttingDown = true;
10107            updateEventDispatchingLocked();
10108            timedout = mStackSupervisor.shutdownLocked(timeout);
10109        }
10110
10111        mAppOpsService.shutdown();
10112        if (mUsageStatsService != null) {
10113            mUsageStatsService.prepareShutdown();
10114        }
10115        mBatteryStatsService.shutdown();
10116        synchronized (this) {
10117            mProcessStats.shutdownLocked();
10118        }
10119        notifyTaskPersisterLocked(null, true);
10120
10121        return timedout;
10122    }
10123
10124    public final void activitySlept(IBinder token) {
10125        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10126
10127        final long origId = Binder.clearCallingIdentity();
10128
10129        synchronized (this) {
10130            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10131            if (r != null) {
10132                mStackSupervisor.activitySleptLocked(r);
10133            }
10134        }
10135
10136        Binder.restoreCallingIdentity(origId);
10137    }
10138
10139    void logLockScreen(String msg) {
10140        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10141                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10142                mWentToSleep + " mSleeping=" + mSleeping);
10143    }
10144
10145    private void comeOutOfSleepIfNeededLocked() {
10146        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10147            if (mSleeping) {
10148                mSleeping = false;
10149                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10150            }
10151        }
10152    }
10153
10154    void wakingUp() {
10155        synchronized(this) {
10156            mWentToSleep = false;
10157            comeOutOfSleepIfNeededLocked();
10158        }
10159    }
10160
10161    void startRunningVoiceLocked() {
10162        if (!mRunningVoice) {
10163            mRunningVoice = true;
10164            comeOutOfSleepIfNeededLocked();
10165        }
10166    }
10167
10168    private void updateEventDispatchingLocked() {
10169        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10170    }
10171
10172    public void setLockScreenShown(boolean shown) {
10173        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10174                != PackageManager.PERMISSION_GRANTED) {
10175            throw new SecurityException("Requires permission "
10176                    + android.Manifest.permission.DEVICE_POWER);
10177        }
10178
10179        synchronized(this) {
10180            long ident = Binder.clearCallingIdentity();
10181            try {
10182                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10183                mLockScreenShown = shown;
10184                comeOutOfSleepIfNeededLocked();
10185            } finally {
10186                Binder.restoreCallingIdentity(ident);
10187            }
10188        }
10189    }
10190
10191    @Override
10192    public void stopAppSwitches() {
10193        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10194                != PackageManager.PERMISSION_GRANTED) {
10195            throw new SecurityException("Requires permission "
10196                    + android.Manifest.permission.STOP_APP_SWITCHES);
10197        }
10198
10199        synchronized(this) {
10200            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10201                    + APP_SWITCH_DELAY_TIME;
10202            mDidAppSwitch = false;
10203            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10204            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10205            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10206        }
10207    }
10208
10209    public void resumeAppSwitches() {
10210        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10211                != PackageManager.PERMISSION_GRANTED) {
10212            throw new SecurityException("Requires permission "
10213                    + android.Manifest.permission.STOP_APP_SWITCHES);
10214        }
10215
10216        synchronized(this) {
10217            // Note that we don't execute any pending app switches... we will
10218            // let those wait until either the timeout, or the next start
10219            // activity request.
10220            mAppSwitchesAllowedTime = 0;
10221        }
10222    }
10223
10224    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10225            int callingPid, int callingUid, String name) {
10226        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10227            return true;
10228        }
10229
10230        int perm = checkComponentPermission(
10231                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10232                sourceUid, -1, true);
10233        if (perm == PackageManager.PERMISSION_GRANTED) {
10234            return true;
10235        }
10236
10237        // If the actual IPC caller is different from the logical source, then
10238        // also see if they are allowed to control app switches.
10239        if (callingUid != -1 && callingUid != sourceUid) {
10240            perm = checkComponentPermission(
10241                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10242                    callingUid, -1, true);
10243            if (perm == PackageManager.PERMISSION_GRANTED) {
10244                return true;
10245            }
10246        }
10247
10248        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10249        return false;
10250    }
10251
10252    public void setDebugApp(String packageName, boolean waitForDebugger,
10253            boolean persistent) {
10254        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10255                "setDebugApp()");
10256
10257        long ident = Binder.clearCallingIdentity();
10258        try {
10259            // Note that this is not really thread safe if there are multiple
10260            // callers into it at the same time, but that's not a situation we
10261            // care about.
10262            if (persistent) {
10263                final ContentResolver resolver = mContext.getContentResolver();
10264                Settings.Global.putString(
10265                    resolver, Settings.Global.DEBUG_APP,
10266                    packageName);
10267                Settings.Global.putInt(
10268                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10269                    waitForDebugger ? 1 : 0);
10270            }
10271
10272            synchronized (this) {
10273                if (!persistent) {
10274                    mOrigDebugApp = mDebugApp;
10275                    mOrigWaitForDebugger = mWaitForDebugger;
10276                }
10277                mDebugApp = packageName;
10278                mWaitForDebugger = waitForDebugger;
10279                mDebugTransient = !persistent;
10280                if (packageName != null) {
10281                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10282                            false, UserHandle.USER_ALL, "set debug app");
10283                }
10284            }
10285        } finally {
10286            Binder.restoreCallingIdentity(ident);
10287        }
10288    }
10289
10290    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10291        synchronized (this) {
10292            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10293            if (!isDebuggable) {
10294                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10295                    throw new SecurityException("Process not debuggable: " + app.packageName);
10296                }
10297            }
10298
10299            mOpenGlTraceApp = processName;
10300        }
10301    }
10302
10303    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10304        synchronized (this) {
10305            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10306            if (!isDebuggable) {
10307                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10308                    throw new SecurityException("Process not debuggable: " + app.packageName);
10309                }
10310            }
10311            mProfileApp = processName;
10312            mProfileFile = profilerInfo.profileFile;
10313            if (mProfileFd != null) {
10314                try {
10315                    mProfileFd.close();
10316                } catch (IOException e) {
10317                }
10318                mProfileFd = null;
10319            }
10320            mProfileFd = profilerInfo.profileFd;
10321            mSamplingInterval = profilerInfo.samplingInterval;
10322            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10323            mProfileType = 0;
10324        }
10325    }
10326
10327    @Override
10328    public void setAlwaysFinish(boolean enabled) {
10329        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10330                "setAlwaysFinish()");
10331
10332        Settings.Global.putInt(
10333                mContext.getContentResolver(),
10334                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10335
10336        synchronized (this) {
10337            mAlwaysFinishActivities = enabled;
10338        }
10339    }
10340
10341    @Override
10342    public void setActivityController(IActivityController controller) {
10343        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10344                "setActivityController()");
10345        synchronized (this) {
10346            mController = controller;
10347            Watchdog.getInstance().setActivityController(controller);
10348        }
10349    }
10350
10351    @Override
10352    public void setUserIsMonkey(boolean userIsMonkey) {
10353        synchronized (this) {
10354            synchronized (mPidsSelfLocked) {
10355                final int callingPid = Binder.getCallingPid();
10356                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10357                if (precessRecord == null) {
10358                    throw new SecurityException("Unknown process: " + callingPid);
10359                }
10360                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10361                    throw new SecurityException("Only an instrumentation process "
10362                            + "with a UiAutomation can call setUserIsMonkey");
10363                }
10364            }
10365            mUserIsMonkey = userIsMonkey;
10366        }
10367    }
10368
10369    @Override
10370    public boolean isUserAMonkey() {
10371        synchronized (this) {
10372            // If there is a controller also implies the user is a monkey.
10373            return (mUserIsMonkey || mController != null);
10374        }
10375    }
10376
10377    public void requestBugReport() {
10378        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10379        SystemProperties.set("ctl.start", "bugreport");
10380    }
10381
10382    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10383        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10384    }
10385
10386    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10387        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10388            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10389        }
10390        return KEY_DISPATCHING_TIMEOUT;
10391    }
10392
10393    @Override
10394    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10395        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10396                != PackageManager.PERMISSION_GRANTED) {
10397            throw new SecurityException("Requires permission "
10398                    + android.Manifest.permission.FILTER_EVENTS);
10399        }
10400        ProcessRecord proc;
10401        long timeout;
10402        synchronized (this) {
10403            synchronized (mPidsSelfLocked) {
10404                proc = mPidsSelfLocked.get(pid);
10405            }
10406            timeout = getInputDispatchingTimeoutLocked(proc);
10407        }
10408
10409        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10410            return -1;
10411        }
10412
10413        return timeout;
10414    }
10415
10416    /**
10417     * Handle input dispatching timeouts.
10418     * Returns whether input dispatching should be aborted or not.
10419     */
10420    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10421            final ActivityRecord activity, final ActivityRecord parent,
10422            final boolean aboveSystem, String reason) {
10423        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10424                != PackageManager.PERMISSION_GRANTED) {
10425            throw new SecurityException("Requires permission "
10426                    + android.Manifest.permission.FILTER_EVENTS);
10427        }
10428
10429        final String annotation;
10430        if (reason == null) {
10431            annotation = "Input dispatching timed out";
10432        } else {
10433            annotation = "Input dispatching timed out (" + reason + ")";
10434        }
10435
10436        if (proc != null) {
10437            synchronized (this) {
10438                if (proc.debugging) {
10439                    return false;
10440                }
10441
10442                if (mDidDexOpt) {
10443                    // Give more time since we were dexopting.
10444                    mDidDexOpt = false;
10445                    return false;
10446                }
10447
10448                if (proc.instrumentationClass != null) {
10449                    Bundle info = new Bundle();
10450                    info.putString("shortMsg", "keyDispatchingTimedOut");
10451                    info.putString("longMsg", annotation);
10452                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10453                    return true;
10454                }
10455            }
10456            mHandler.post(new Runnable() {
10457                @Override
10458                public void run() {
10459                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10460                }
10461            });
10462        }
10463
10464        return true;
10465    }
10466
10467    public Bundle getAssistContextExtras(int requestType) {
10468        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10469                UserHandle.getCallingUserId());
10470        if (pae == null) {
10471            return null;
10472        }
10473        synchronized (pae) {
10474            while (!pae.haveResult) {
10475                try {
10476                    pae.wait();
10477                } catch (InterruptedException e) {
10478                }
10479            }
10480            if (pae.result != null) {
10481                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10482            }
10483        }
10484        synchronized (this) {
10485            mPendingAssistExtras.remove(pae);
10486            mHandler.removeCallbacks(pae);
10487        }
10488        return pae.extras;
10489    }
10490
10491    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10492            int userHandle) {
10493        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10494                "getAssistContextExtras()");
10495        PendingAssistExtras pae;
10496        Bundle extras = new Bundle();
10497        synchronized (this) {
10498            ActivityRecord activity = getFocusedStack().mResumedActivity;
10499            if (activity == null) {
10500                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10501                return null;
10502            }
10503            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10504            if (activity.app == null || activity.app.thread == null) {
10505                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10506                return null;
10507            }
10508            if (activity.app.pid == Binder.getCallingPid()) {
10509                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10510                return null;
10511            }
10512            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10513            try {
10514                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10515                        requestType);
10516                mPendingAssistExtras.add(pae);
10517                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10518            } catch (RemoteException e) {
10519                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10520                return null;
10521            }
10522            return pae;
10523        }
10524    }
10525
10526    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10527        PendingAssistExtras pae = (PendingAssistExtras)token;
10528        synchronized (pae) {
10529            pae.result = extras;
10530            pae.haveResult = true;
10531            pae.notifyAll();
10532            if (pae.intent == null) {
10533                // Caller is just waiting for the result.
10534                return;
10535            }
10536        }
10537
10538        // We are now ready to launch the assist activity.
10539        synchronized (this) {
10540            boolean exists = mPendingAssistExtras.remove(pae);
10541            mHandler.removeCallbacks(pae);
10542            if (!exists) {
10543                // Timed out.
10544                return;
10545            }
10546        }
10547        pae.intent.replaceExtras(extras);
10548        if (pae.hint != null) {
10549            pae.intent.putExtra(pae.hint, true);
10550        }
10551        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10552                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10553                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10554        closeSystemDialogs("assist");
10555        try {
10556            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10557        } catch (ActivityNotFoundException e) {
10558            Slog.w(TAG, "No activity to handle assist action.", e);
10559        }
10560    }
10561
10562    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10563        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10564    }
10565
10566    public void registerProcessObserver(IProcessObserver observer) {
10567        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10568                "registerProcessObserver()");
10569        synchronized (this) {
10570            mProcessObservers.register(observer);
10571        }
10572    }
10573
10574    @Override
10575    public void unregisterProcessObserver(IProcessObserver observer) {
10576        synchronized (this) {
10577            mProcessObservers.unregister(observer);
10578        }
10579    }
10580
10581    @Override
10582    public boolean convertFromTranslucent(IBinder token) {
10583        final long origId = Binder.clearCallingIdentity();
10584        try {
10585            synchronized (this) {
10586                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10587                if (r == null) {
10588                    return false;
10589                }
10590                final boolean translucentChanged = r.changeWindowTranslucency(true);
10591                if (translucentChanged) {
10592                    r.task.stack.releaseBackgroundResources();
10593                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10594                }
10595                mWindowManager.setAppFullscreen(token, true);
10596                return translucentChanged;
10597            }
10598        } finally {
10599            Binder.restoreCallingIdentity(origId);
10600        }
10601    }
10602
10603    @Override
10604    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10605        final long origId = Binder.clearCallingIdentity();
10606        try {
10607            synchronized (this) {
10608                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10609                if (r == null) {
10610                    return false;
10611                }
10612                int index = r.task.mActivities.lastIndexOf(r);
10613                if (index > 0) {
10614                    ActivityRecord under = r.task.mActivities.get(index - 1);
10615                    under.returningOptions = options;
10616                }
10617                final boolean translucentChanged = r.changeWindowTranslucency(false);
10618                if (translucentChanged) {
10619                    r.task.stack.convertToTranslucent(r);
10620                }
10621                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10622                mWindowManager.setAppFullscreen(token, false);
10623                return translucentChanged;
10624            }
10625        } finally {
10626            Binder.restoreCallingIdentity(origId);
10627        }
10628    }
10629
10630    @Override
10631    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10632        final long origId = Binder.clearCallingIdentity();
10633        try {
10634            synchronized (this) {
10635                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10636                if (r != null) {
10637                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10638                }
10639            }
10640            return false;
10641        } finally {
10642            Binder.restoreCallingIdentity(origId);
10643        }
10644    }
10645
10646    @Override
10647    public boolean isBackgroundVisibleBehind(IBinder token) {
10648        final long origId = Binder.clearCallingIdentity();
10649        try {
10650            synchronized (this) {
10651                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10652                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10653                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10654                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10655                return visible;
10656            }
10657        } finally {
10658            Binder.restoreCallingIdentity(origId);
10659        }
10660    }
10661
10662    @Override
10663    public ActivityOptions getActivityOptions(IBinder token) {
10664        final long origId = Binder.clearCallingIdentity();
10665        try {
10666            synchronized (this) {
10667                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10668                if (r != null) {
10669                    final ActivityOptions activityOptions = r.pendingOptions;
10670                    r.pendingOptions = null;
10671                    return activityOptions;
10672                }
10673                return null;
10674            }
10675        } finally {
10676            Binder.restoreCallingIdentity(origId);
10677        }
10678    }
10679
10680    @Override
10681    public void setImmersive(IBinder token, boolean immersive) {
10682        synchronized(this) {
10683            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10684            if (r == null) {
10685                throw new IllegalArgumentException();
10686            }
10687            r.immersive = immersive;
10688
10689            // update associated state if we're frontmost
10690            if (r == mFocusedActivity) {
10691                if (DEBUG_IMMERSIVE) {
10692                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10693                }
10694                applyUpdateLockStateLocked(r);
10695            }
10696        }
10697    }
10698
10699    @Override
10700    public boolean isImmersive(IBinder token) {
10701        synchronized (this) {
10702            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10703            if (r == null) {
10704                throw new IllegalArgumentException();
10705            }
10706            return r.immersive;
10707        }
10708    }
10709
10710    public boolean isTopActivityImmersive() {
10711        enforceNotIsolatedCaller("startActivity");
10712        synchronized (this) {
10713            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10714            return (r != null) ? r.immersive : false;
10715        }
10716    }
10717
10718    @Override
10719    public boolean isTopOfTask(IBinder token) {
10720        synchronized (this) {
10721            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10722            if (r == null) {
10723                throw new IllegalArgumentException();
10724            }
10725            return r.task.getTopActivity() == r;
10726        }
10727    }
10728
10729    public final void enterSafeMode() {
10730        synchronized(this) {
10731            // It only makes sense to do this before the system is ready
10732            // and started launching other packages.
10733            if (!mSystemReady) {
10734                try {
10735                    AppGlobals.getPackageManager().enterSafeMode();
10736                } catch (RemoteException e) {
10737                }
10738            }
10739
10740            mSafeMode = true;
10741        }
10742    }
10743
10744    public final void showSafeModeOverlay() {
10745        View v = LayoutInflater.from(mContext).inflate(
10746                com.android.internal.R.layout.safe_mode, null);
10747        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10748        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10749        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10750        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10751        lp.gravity = Gravity.BOTTOM | Gravity.START;
10752        lp.format = v.getBackground().getOpacity();
10753        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10754                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10755        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10756        ((WindowManager)mContext.getSystemService(
10757                Context.WINDOW_SERVICE)).addView(v, lp);
10758    }
10759
10760    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10761        if (!(sender instanceof PendingIntentRecord)) {
10762            return;
10763        }
10764        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10765        synchronized (stats) {
10766            if (mBatteryStatsService.isOnBattery()) {
10767                mBatteryStatsService.enforceCallingPermission();
10768                PendingIntentRecord rec = (PendingIntentRecord)sender;
10769                int MY_UID = Binder.getCallingUid();
10770                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10771                BatteryStatsImpl.Uid.Pkg pkg =
10772                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10773                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10774                pkg.incWakeupsLocked();
10775            }
10776        }
10777    }
10778
10779    public boolean killPids(int[] pids, String pReason, boolean secure) {
10780        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10781            throw new SecurityException("killPids only available to the system");
10782        }
10783        String reason = (pReason == null) ? "Unknown" : pReason;
10784        // XXX Note: don't acquire main activity lock here, because the window
10785        // manager calls in with its locks held.
10786
10787        boolean killed = false;
10788        synchronized (mPidsSelfLocked) {
10789            int[] types = new int[pids.length];
10790            int worstType = 0;
10791            for (int i=0; i<pids.length; i++) {
10792                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10793                if (proc != null) {
10794                    int type = proc.setAdj;
10795                    types[i] = type;
10796                    if (type > worstType) {
10797                        worstType = type;
10798                    }
10799                }
10800            }
10801
10802            // If the worst oom_adj is somewhere in the cached proc LRU range,
10803            // then constrain it so we will kill all cached procs.
10804            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10805                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10806                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10807            }
10808
10809            // If this is not a secure call, don't let it kill processes that
10810            // are important.
10811            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10812                worstType = ProcessList.SERVICE_ADJ;
10813            }
10814
10815            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10816            for (int i=0; i<pids.length; i++) {
10817                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10818                if (proc == null) {
10819                    continue;
10820                }
10821                int adj = proc.setAdj;
10822                if (adj >= worstType && !proc.killedByAm) {
10823                    proc.kill(reason, true);
10824                    killed = true;
10825                }
10826            }
10827        }
10828        return killed;
10829    }
10830
10831    @Override
10832    public void killUid(int uid, String reason) {
10833        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10834            throw new SecurityException("killUid only available to the system");
10835        }
10836        synchronized (this) {
10837            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10838                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10839                    reason != null ? reason : "kill uid");
10840        }
10841    }
10842
10843    @Override
10844    public boolean killProcessesBelowForeground(String reason) {
10845        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10846            throw new SecurityException("killProcessesBelowForeground() only available to system");
10847        }
10848
10849        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10850    }
10851
10852    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10853        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10854            throw new SecurityException("killProcessesBelowAdj() only available to system");
10855        }
10856
10857        boolean killed = false;
10858        synchronized (mPidsSelfLocked) {
10859            final int size = mPidsSelfLocked.size();
10860            for (int i = 0; i < size; i++) {
10861                final int pid = mPidsSelfLocked.keyAt(i);
10862                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10863                if (proc == null) continue;
10864
10865                final int adj = proc.setAdj;
10866                if (adj > belowAdj && !proc.killedByAm) {
10867                    proc.kill(reason, true);
10868                    killed = true;
10869                }
10870            }
10871        }
10872        return killed;
10873    }
10874
10875    @Override
10876    public void hang(final IBinder who, boolean allowRestart) {
10877        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10878                != PackageManager.PERMISSION_GRANTED) {
10879            throw new SecurityException("Requires permission "
10880                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10881        }
10882
10883        final IBinder.DeathRecipient death = new DeathRecipient() {
10884            @Override
10885            public void binderDied() {
10886                synchronized (this) {
10887                    notifyAll();
10888                }
10889            }
10890        };
10891
10892        try {
10893            who.linkToDeath(death, 0);
10894        } catch (RemoteException e) {
10895            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10896            return;
10897        }
10898
10899        synchronized (this) {
10900            Watchdog.getInstance().setAllowRestart(allowRestart);
10901            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10902            synchronized (death) {
10903                while (who.isBinderAlive()) {
10904                    try {
10905                        death.wait();
10906                    } catch (InterruptedException e) {
10907                    }
10908                }
10909            }
10910            Watchdog.getInstance().setAllowRestart(true);
10911        }
10912    }
10913
10914    @Override
10915    public void restart() {
10916        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10917                != PackageManager.PERMISSION_GRANTED) {
10918            throw new SecurityException("Requires permission "
10919                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10920        }
10921
10922        Log.i(TAG, "Sending shutdown broadcast...");
10923
10924        BroadcastReceiver br = new BroadcastReceiver() {
10925            @Override public void onReceive(Context context, Intent intent) {
10926                // Now the broadcast is done, finish up the low-level shutdown.
10927                Log.i(TAG, "Shutting down activity manager...");
10928                shutdown(10000);
10929                Log.i(TAG, "Shutdown complete, restarting!");
10930                Process.killProcess(Process.myPid());
10931                System.exit(10);
10932            }
10933        };
10934
10935        // First send the high-level shut down broadcast.
10936        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10937        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10938        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10939        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10940        mContext.sendOrderedBroadcastAsUser(intent,
10941                UserHandle.ALL, null, br, mHandler, 0, null, null);
10942        */
10943        br.onReceive(mContext, intent);
10944    }
10945
10946    private long getLowRamTimeSinceIdle(long now) {
10947        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10948    }
10949
10950    @Override
10951    public void performIdleMaintenance() {
10952        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10953                != PackageManager.PERMISSION_GRANTED) {
10954            throw new SecurityException("Requires permission "
10955                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10956        }
10957
10958        synchronized (this) {
10959            final long now = SystemClock.uptimeMillis();
10960            final long timeSinceLastIdle = now - mLastIdleTime;
10961            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10962            mLastIdleTime = now;
10963            mLowRamTimeSinceLastIdle = 0;
10964            if (mLowRamStartTime != 0) {
10965                mLowRamStartTime = now;
10966            }
10967
10968            StringBuilder sb = new StringBuilder(128);
10969            sb.append("Idle maintenance over ");
10970            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10971            sb.append(" low RAM for ");
10972            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10973            Slog.i(TAG, sb.toString());
10974
10975            // If at least 1/3 of our time since the last idle period has been spent
10976            // with RAM low, then we want to kill processes.
10977            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10978
10979            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10980                ProcessRecord proc = mLruProcesses.get(i);
10981                if (proc.notCachedSinceIdle) {
10982                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10983                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10984                        if (doKilling && proc.initialIdlePss != 0
10985                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10986                            proc.kill("idle maint (pss " + proc.lastPss
10987                                    + " from " + proc.initialIdlePss + ")", true);
10988                        }
10989                    }
10990                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10991                    proc.notCachedSinceIdle = true;
10992                    proc.initialIdlePss = 0;
10993                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10994                            isSleeping(), now);
10995                }
10996            }
10997
10998            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10999            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11000        }
11001    }
11002
11003    private void retrieveSettings() {
11004        final ContentResolver resolver = mContext.getContentResolver();
11005        String debugApp = Settings.Global.getString(
11006            resolver, Settings.Global.DEBUG_APP);
11007        boolean waitForDebugger = Settings.Global.getInt(
11008            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11009        boolean alwaysFinishActivities = Settings.Global.getInt(
11010            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11011        boolean forceRtl = Settings.Global.getInt(
11012                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11013        // Transfer any global setting for forcing RTL layout, into a System Property
11014        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11015
11016        Configuration configuration = new Configuration();
11017        Settings.System.getConfiguration(resolver, configuration);
11018        if (forceRtl) {
11019            // This will take care of setting the correct layout direction flags
11020            configuration.setLayoutDirection(configuration.locale);
11021        }
11022
11023        synchronized (this) {
11024            mDebugApp = mOrigDebugApp = debugApp;
11025            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11026            mAlwaysFinishActivities = alwaysFinishActivities;
11027            // This happens before any activities are started, so we can
11028            // change mConfiguration in-place.
11029            updateConfigurationLocked(configuration, null, false, true);
11030            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11031        }
11032    }
11033
11034    /** Loads resources after the current configuration has been set. */
11035    private void loadResourcesOnSystemReady() {
11036        final Resources res = mContext.getResources();
11037        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11038        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11039        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11040    }
11041
11042    public boolean testIsSystemReady() {
11043        // no need to synchronize(this) just to read & return the value
11044        return mSystemReady;
11045    }
11046
11047    private static File getCalledPreBootReceiversFile() {
11048        File dataDir = Environment.getDataDirectory();
11049        File systemDir = new File(dataDir, "system");
11050        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11051        return fname;
11052    }
11053
11054    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11055        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11056        File file = getCalledPreBootReceiversFile();
11057        FileInputStream fis = null;
11058        try {
11059            fis = new FileInputStream(file);
11060            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11061            int fvers = dis.readInt();
11062            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11063                String vers = dis.readUTF();
11064                String codename = dis.readUTF();
11065                String build = dis.readUTF();
11066                if (android.os.Build.VERSION.RELEASE.equals(vers)
11067                        && android.os.Build.VERSION.CODENAME.equals(codename)
11068                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11069                    int num = dis.readInt();
11070                    while (num > 0) {
11071                        num--;
11072                        String pkg = dis.readUTF();
11073                        String cls = dis.readUTF();
11074                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11075                    }
11076                }
11077            }
11078        } catch (FileNotFoundException e) {
11079        } catch (IOException e) {
11080            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11081        } finally {
11082            if (fis != null) {
11083                try {
11084                    fis.close();
11085                } catch (IOException e) {
11086                }
11087            }
11088        }
11089        return lastDoneReceivers;
11090    }
11091
11092    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11093        File file = getCalledPreBootReceiversFile();
11094        FileOutputStream fos = null;
11095        DataOutputStream dos = null;
11096        try {
11097            fos = new FileOutputStream(file);
11098            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11099            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11100            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11101            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11102            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11103            dos.writeInt(list.size());
11104            for (int i=0; i<list.size(); i++) {
11105                dos.writeUTF(list.get(i).getPackageName());
11106                dos.writeUTF(list.get(i).getClassName());
11107            }
11108        } catch (IOException e) {
11109            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11110            file.delete();
11111        } finally {
11112            FileUtils.sync(fos);
11113            if (dos != null) {
11114                try {
11115                    dos.close();
11116                } catch (IOException e) {
11117                    // TODO Auto-generated catch block
11118                    e.printStackTrace();
11119                }
11120            }
11121        }
11122    }
11123
11124    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11125            ArrayList<ComponentName> doneReceivers, int userId) {
11126        boolean waitingUpdate = false;
11127        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11128        List<ResolveInfo> ris = null;
11129        try {
11130            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11131                    intent, null, 0, userId);
11132        } catch (RemoteException e) {
11133        }
11134        if (ris != null) {
11135            for (int i=ris.size()-1; i>=0; i--) {
11136                if ((ris.get(i).activityInfo.applicationInfo.flags
11137                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11138                    ris.remove(i);
11139                }
11140            }
11141            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11142
11143            // For User 0, load the version number. When delivering to a new user, deliver
11144            // to all receivers.
11145            if (userId == UserHandle.USER_OWNER) {
11146                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11147                for (int i=0; i<ris.size(); i++) {
11148                    ActivityInfo ai = ris.get(i).activityInfo;
11149                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11150                    if (lastDoneReceivers.contains(comp)) {
11151                        // We already did the pre boot receiver for this app with the current
11152                        // platform version, so don't do it again...
11153                        ris.remove(i);
11154                        i--;
11155                        // ...however, do keep it as one that has been done, so we don't
11156                        // forget about it when rewriting the file of last done receivers.
11157                        doneReceivers.add(comp);
11158                    }
11159                }
11160            }
11161
11162            // If primary user, send broadcast to all available users, else just to userId
11163            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11164                    : new int[] { userId };
11165            for (int i = 0; i < ris.size(); i++) {
11166                ActivityInfo ai = ris.get(i).activityInfo;
11167                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11168                doneReceivers.add(comp);
11169                intent.setComponent(comp);
11170                for (int j=0; j<users.length; j++) {
11171                    IIntentReceiver finisher = null;
11172                    // On last receiver and user, set up a completion callback
11173                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11174                        finisher = new IIntentReceiver.Stub() {
11175                            public void performReceive(Intent intent, int resultCode,
11176                                    String data, Bundle extras, boolean ordered,
11177                                    boolean sticky, int sendingUser) {
11178                                // The raw IIntentReceiver interface is called
11179                                // with the AM lock held, so redispatch to
11180                                // execute our code without the lock.
11181                                mHandler.post(onFinishCallback);
11182                            }
11183                        };
11184                    }
11185                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11186                            + " for user " + users[j]);
11187                    broadcastIntentLocked(null, null, intent, null, finisher,
11188                            0, null, null, null, AppOpsManager.OP_NONE,
11189                            true, false, MY_PID, Process.SYSTEM_UID,
11190                            users[j]);
11191                    if (finisher != null) {
11192                        waitingUpdate = true;
11193                    }
11194                }
11195            }
11196        }
11197
11198        return waitingUpdate;
11199    }
11200
11201    public void systemReady(final Runnable goingCallback) {
11202        synchronized(this) {
11203            if (mSystemReady) {
11204                // If we're done calling all the receivers, run the next "boot phase" passed in
11205                // by the SystemServer
11206                if (goingCallback != null) {
11207                    goingCallback.run();
11208                }
11209                return;
11210            }
11211
11212            // Make sure we have the current profile info, since it is needed for
11213            // security checks.
11214            updateCurrentProfileIdsLocked();
11215
11216            if (mRecentTasks == null) {
11217                mRecentTasks = mTaskPersister.restoreTasksLocked();
11218                if (!mRecentTasks.isEmpty()) {
11219                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11220                }
11221                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11222                mTaskPersister.startPersisting();
11223            }
11224
11225            // Check to see if there are any update receivers to run.
11226            if (!mDidUpdate) {
11227                if (mWaitingUpdate) {
11228                    return;
11229                }
11230                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11231                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11232                    public void run() {
11233                        synchronized (ActivityManagerService.this) {
11234                            mDidUpdate = true;
11235                        }
11236                        writeLastDonePreBootReceivers(doneReceivers);
11237                        showBootMessage(mContext.getText(
11238                                R.string.android_upgrading_complete),
11239                                false);
11240                        systemReady(goingCallback);
11241                    }
11242                }, doneReceivers, UserHandle.USER_OWNER);
11243
11244                if (mWaitingUpdate) {
11245                    return;
11246                }
11247                mDidUpdate = true;
11248            }
11249
11250            mAppOpsService.systemReady();
11251            mSystemReady = true;
11252        }
11253
11254        ArrayList<ProcessRecord> procsToKill = null;
11255        synchronized(mPidsSelfLocked) {
11256            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11257                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11258                if (!isAllowedWhileBooting(proc.info)){
11259                    if (procsToKill == null) {
11260                        procsToKill = new ArrayList<ProcessRecord>();
11261                    }
11262                    procsToKill.add(proc);
11263                }
11264            }
11265        }
11266
11267        synchronized(this) {
11268            if (procsToKill != null) {
11269                for (int i=procsToKill.size()-1; i>=0; i--) {
11270                    ProcessRecord proc = procsToKill.get(i);
11271                    Slog.i(TAG, "Removing system update proc: " + proc);
11272                    removeProcessLocked(proc, true, false, "system update done");
11273                }
11274            }
11275
11276            // Now that we have cleaned up any update processes, we
11277            // are ready to start launching real processes and know that
11278            // we won't trample on them any more.
11279            mProcessesReady = true;
11280        }
11281
11282        Slog.i(TAG, "System now ready");
11283        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11284            SystemClock.uptimeMillis());
11285
11286        synchronized(this) {
11287            // Make sure we have no pre-ready processes sitting around.
11288
11289            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11290                ResolveInfo ri = mContext.getPackageManager()
11291                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11292                                STOCK_PM_FLAGS);
11293                CharSequence errorMsg = null;
11294                if (ri != null) {
11295                    ActivityInfo ai = ri.activityInfo;
11296                    ApplicationInfo app = ai.applicationInfo;
11297                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11298                        mTopAction = Intent.ACTION_FACTORY_TEST;
11299                        mTopData = null;
11300                        mTopComponent = new ComponentName(app.packageName,
11301                                ai.name);
11302                    } else {
11303                        errorMsg = mContext.getResources().getText(
11304                                com.android.internal.R.string.factorytest_not_system);
11305                    }
11306                } else {
11307                    errorMsg = mContext.getResources().getText(
11308                            com.android.internal.R.string.factorytest_no_action);
11309                }
11310                if (errorMsg != null) {
11311                    mTopAction = null;
11312                    mTopData = null;
11313                    mTopComponent = null;
11314                    Message msg = Message.obtain();
11315                    msg.what = SHOW_FACTORY_ERROR_MSG;
11316                    msg.getData().putCharSequence("msg", errorMsg);
11317                    mHandler.sendMessage(msg);
11318                }
11319            }
11320        }
11321
11322        retrieveSettings();
11323        loadResourcesOnSystemReady();
11324
11325        synchronized (this) {
11326            readGrantedUriPermissionsLocked();
11327        }
11328
11329        if (goingCallback != null) goingCallback.run();
11330
11331        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11332                Integer.toString(mCurrentUserId), mCurrentUserId);
11333        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11334                Integer.toString(mCurrentUserId), mCurrentUserId);
11335        mSystemServiceManager.startUser(mCurrentUserId);
11336
11337        synchronized (this) {
11338            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11339                try {
11340                    List apps = AppGlobals.getPackageManager().
11341                        getPersistentApplications(STOCK_PM_FLAGS);
11342                    if (apps != null) {
11343                        int N = apps.size();
11344                        int i;
11345                        for (i=0; i<N; i++) {
11346                            ApplicationInfo info
11347                                = (ApplicationInfo)apps.get(i);
11348                            if (info != null &&
11349                                    !info.packageName.equals("android")) {
11350                                addAppLocked(info, false, null /* ABI override */);
11351                            }
11352                        }
11353                    }
11354                } catch (RemoteException ex) {
11355                    // pm is in same process, this will never happen.
11356                }
11357            }
11358
11359            // Start up initial activity.
11360            mBooting = true;
11361            startHomeActivityLocked(mCurrentUserId);
11362
11363            try {
11364                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11365                    Message msg = Message.obtain();
11366                    msg.what = SHOW_UID_ERROR_MSG;
11367                    mHandler.sendMessage(msg);
11368                }
11369            } catch (RemoteException e) {
11370            }
11371
11372            long ident = Binder.clearCallingIdentity();
11373            try {
11374                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11375                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11376                        | Intent.FLAG_RECEIVER_FOREGROUND);
11377                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11378                broadcastIntentLocked(null, null, intent,
11379                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11380                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11381                intent = new Intent(Intent.ACTION_USER_STARTING);
11382                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11383                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11384                broadcastIntentLocked(null, null, intent,
11385                        null, new IIntentReceiver.Stub() {
11386                            @Override
11387                            public void performReceive(Intent intent, int resultCode, String data,
11388                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11389                                    throws RemoteException {
11390                            }
11391                        }, 0, null, null,
11392                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11393                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11394            } catch (Throwable t) {
11395                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11396            } finally {
11397                Binder.restoreCallingIdentity(ident);
11398            }
11399            mStackSupervisor.resumeTopActivitiesLocked();
11400            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11401        }
11402    }
11403
11404    private boolean makeAppCrashingLocked(ProcessRecord app,
11405            String shortMsg, String longMsg, String stackTrace) {
11406        app.crashing = true;
11407        app.crashingReport = generateProcessError(app,
11408                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11409        startAppProblemLocked(app);
11410        app.stopFreezingAllLocked();
11411        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11412    }
11413
11414    private void makeAppNotRespondingLocked(ProcessRecord app,
11415            String activity, String shortMsg, String longMsg) {
11416        app.notResponding = true;
11417        app.notRespondingReport = generateProcessError(app,
11418                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11419                activity, shortMsg, longMsg, null);
11420        startAppProblemLocked(app);
11421        app.stopFreezingAllLocked();
11422    }
11423
11424    /**
11425     * Generate a process error record, suitable for attachment to a ProcessRecord.
11426     *
11427     * @param app The ProcessRecord in which the error occurred.
11428     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11429     *                      ActivityManager.AppErrorStateInfo
11430     * @param activity The activity associated with the crash, if known.
11431     * @param shortMsg Short message describing the crash.
11432     * @param longMsg Long message describing the crash.
11433     * @param stackTrace Full crash stack trace, may be null.
11434     *
11435     * @return Returns a fully-formed AppErrorStateInfo record.
11436     */
11437    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11438            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11439        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11440
11441        report.condition = condition;
11442        report.processName = app.processName;
11443        report.pid = app.pid;
11444        report.uid = app.info.uid;
11445        report.tag = activity;
11446        report.shortMsg = shortMsg;
11447        report.longMsg = longMsg;
11448        report.stackTrace = stackTrace;
11449
11450        return report;
11451    }
11452
11453    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11454        synchronized (this) {
11455            app.crashing = false;
11456            app.crashingReport = null;
11457            app.notResponding = false;
11458            app.notRespondingReport = null;
11459            if (app.anrDialog == fromDialog) {
11460                app.anrDialog = null;
11461            }
11462            if (app.waitDialog == fromDialog) {
11463                app.waitDialog = null;
11464            }
11465            if (app.pid > 0 && app.pid != MY_PID) {
11466                handleAppCrashLocked(app, null, null, null);
11467                app.kill("user request after error", true);
11468            }
11469        }
11470    }
11471
11472    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11473            String stackTrace) {
11474        long now = SystemClock.uptimeMillis();
11475
11476        Long crashTime;
11477        if (!app.isolated) {
11478            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11479        } else {
11480            crashTime = null;
11481        }
11482        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11483            // This process loses!
11484            Slog.w(TAG, "Process " + app.info.processName
11485                    + " has crashed too many times: killing!");
11486            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11487                    app.userId, app.info.processName, app.uid);
11488            mStackSupervisor.handleAppCrashLocked(app);
11489            if (!app.persistent) {
11490                // We don't want to start this process again until the user
11491                // explicitly does so...  but for persistent process, we really
11492                // need to keep it running.  If a persistent process is actually
11493                // repeatedly crashing, then badness for everyone.
11494                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11495                        app.info.processName);
11496                if (!app.isolated) {
11497                    // XXX We don't have a way to mark isolated processes
11498                    // as bad, since they don't have a peristent identity.
11499                    mBadProcesses.put(app.info.processName, app.uid,
11500                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11501                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11502                }
11503                app.bad = true;
11504                app.removed = true;
11505                // Don't let services in this process be restarted and potentially
11506                // annoy the user repeatedly.  Unless it is persistent, since those
11507                // processes run critical code.
11508                removeProcessLocked(app, false, false, "crash");
11509                mStackSupervisor.resumeTopActivitiesLocked();
11510                return false;
11511            }
11512            mStackSupervisor.resumeTopActivitiesLocked();
11513        } else {
11514            mStackSupervisor.finishTopRunningActivityLocked(app);
11515        }
11516
11517        // Bump up the crash count of any services currently running in the proc.
11518        for (int i=app.services.size()-1; i>=0; i--) {
11519            // Any services running in the application need to be placed
11520            // back in the pending list.
11521            ServiceRecord sr = app.services.valueAt(i);
11522            sr.crashCount++;
11523        }
11524
11525        // If the crashing process is what we consider to be the "home process" and it has been
11526        // replaced by a third-party app, clear the package preferred activities from packages
11527        // with a home activity running in the process to prevent a repeatedly crashing app
11528        // from blocking the user to manually clear the list.
11529        final ArrayList<ActivityRecord> activities = app.activities;
11530        if (app == mHomeProcess && activities.size() > 0
11531                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11532            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11533                final ActivityRecord r = activities.get(activityNdx);
11534                if (r.isHomeActivity()) {
11535                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11536                    try {
11537                        ActivityThread.getPackageManager()
11538                                .clearPackagePreferredActivities(r.packageName);
11539                    } catch (RemoteException c) {
11540                        // pm is in same process, this will never happen.
11541                    }
11542                }
11543            }
11544        }
11545
11546        if (!app.isolated) {
11547            // XXX Can't keep track of crash times for isolated processes,
11548            // because they don't have a perisistent identity.
11549            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11550        }
11551
11552        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11553        return true;
11554    }
11555
11556    void startAppProblemLocked(ProcessRecord app) {
11557        // If this app is not running under the current user, then we
11558        // can't give it a report button because that would require
11559        // launching the report UI under a different user.
11560        app.errorReportReceiver = null;
11561
11562        for (int userId : mCurrentProfileIds) {
11563            if (app.userId == userId) {
11564                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11565                        mContext, app.info.packageName, app.info.flags);
11566            }
11567        }
11568        skipCurrentReceiverLocked(app);
11569    }
11570
11571    void skipCurrentReceiverLocked(ProcessRecord app) {
11572        for (BroadcastQueue queue : mBroadcastQueues) {
11573            queue.skipCurrentReceiverLocked(app);
11574        }
11575    }
11576
11577    /**
11578     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11579     * The application process will exit immediately after this call returns.
11580     * @param app object of the crashing app, null for the system server
11581     * @param crashInfo describing the exception
11582     */
11583    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11584        ProcessRecord r = findAppProcess(app, "Crash");
11585        final String processName = app == null ? "system_server"
11586                : (r == null ? "unknown" : r.processName);
11587
11588        handleApplicationCrashInner("crash", r, processName, crashInfo);
11589    }
11590
11591    /* Native crash reporting uses this inner version because it needs to be somewhat
11592     * decoupled from the AM-managed cleanup lifecycle
11593     */
11594    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11595            ApplicationErrorReport.CrashInfo crashInfo) {
11596        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11597                UserHandle.getUserId(Binder.getCallingUid()), processName,
11598                r == null ? -1 : r.info.flags,
11599                crashInfo.exceptionClassName,
11600                crashInfo.exceptionMessage,
11601                crashInfo.throwFileName,
11602                crashInfo.throwLineNumber);
11603
11604        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11605
11606        crashApplication(r, crashInfo);
11607    }
11608
11609    public void handleApplicationStrictModeViolation(
11610            IBinder app,
11611            int violationMask,
11612            StrictMode.ViolationInfo info) {
11613        ProcessRecord r = findAppProcess(app, "StrictMode");
11614        if (r == null) {
11615            return;
11616        }
11617
11618        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11619            Integer stackFingerprint = info.hashCode();
11620            boolean logIt = true;
11621            synchronized (mAlreadyLoggedViolatedStacks) {
11622                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11623                    logIt = false;
11624                    // TODO: sub-sample into EventLog for these, with
11625                    // the info.durationMillis?  Then we'd get
11626                    // the relative pain numbers, without logging all
11627                    // the stack traces repeatedly.  We'd want to do
11628                    // likewise in the client code, which also does
11629                    // dup suppression, before the Binder call.
11630                } else {
11631                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11632                        mAlreadyLoggedViolatedStacks.clear();
11633                    }
11634                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11635                }
11636            }
11637            if (logIt) {
11638                logStrictModeViolationToDropBox(r, info);
11639            }
11640        }
11641
11642        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11643            AppErrorResult result = new AppErrorResult();
11644            synchronized (this) {
11645                final long origId = Binder.clearCallingIdentity();
11646
11647                Message msg = Message.obtain();
11648                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11649                HashMap<String, Object> data = new HashMap<String, Object>();
11650                data.put("result", result);
11651                data.put("app", r);
11652                data.put("violationMask", violationMask);
11653                data.put("info", info);
11654                msg.obj = data;
11655                mHandler.sendMessage(msg);
11656
11657                Binder.restoreCallingIdentity(origId);
11658            }
11659            int res = result.get();
11660            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11661        }
11662    }
11663
11664    // Depending on the policy in effect, there could be a bunch of
11665    // these in quick succession so we try to batch these together to
11666    // minimize disk writes, number of dropbox entries, and maximize
11667    // compression, by having more fewer, larger records.
11668    private void logStrictModeViolationToDropBox(
11669            ProcessRecord process,
11670            StrictMode.ViolationInfo info) {
11671        if (info == null) {
11672            return;
11673        }
11674        final boolean isSystemApp = process == null ||
11675                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11676                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11677        final String processName = process == null ? "unknown" : process.processName;
11678        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11679        final DropBoxManager dbox = (DropBoxManager)
11680                mContext.getSystemService(Context.DROPBOX_SERVICE);
11681
11682        // Exit early if the dropbox isn't configured to accept this report type.
11683        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11684
11685        boolean bufferWasEmpty;
11686        boolean needsFlush;
11687        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11688        synchronized (sb) {
11689            bufferWasEmpty = sb.length() == 0;
11690            appendDropBoxProcessHeaders(process, processName, sb);
11691            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11692            sb.append("System-App: ").append(isSystemApp).append("\n");
11693            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11694            if (info.violationNumThisLoop != 0) {
11695                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11696            }
11697            if (info.numAnimationsRunning != 0) {
11698                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11699            }
11700            if (info.broadcastIntentAction != null) {
11701                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11702            }
11703            if (info.durationMillis != -1) {
11704                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11705            }
11706            if (info.numInstances != -1) {
11707                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11708            }
11709            if (info.tags != null) {
11710                for (String tag : info.tags) {
11711                    sb.append("Span-Tag: ").append(tag).append("\n");
11712                }
11713            }
11714            sb.append("\n");
11715            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11716                sb.append(info.crashInfo.stackTrace);
11717            }
11718            sb.append("\n");
11719
11720            // Only buffer up to ~64k.  Various logging bits truncate
11721            // things at 128k.
11722            needsFlush = (sb.length() > 64 * 1024);
11723        }
11724
11725        // Flush immediately if the buffer's grown too large, or this
11726        // is a non-system app.  Non-system apps are isolated with a
11727        // different tag & policy and not batched.
11728        //
11729        // Batching is useful during internal testing with
11730        // StrictMode settings turned up high.  Without batching,
11731        // thousands of separate files could be created on boot.
11732        if (!isSystemApp || needsFlush) {
11733            new Thread("Error dump: " + dropboxTag) {
11734                @Override
11735                public void run() {
11736                    String report;
11737                    synchronized (sb) {
11738                        report = sb.toString();
11739                        sb.delete(0, sb.length());
11740                        sb.trimToSize();
11741                    }
11742                    if (report.length() != 0) {
11743                        dbox.addText(dropboxTag, report);
11744                    }
11745                }
11746            }.start();
11747            return;
11748        }
11749
11750        // System app batching:
11751        if (!bufferWasEmpty) {
11752            // An existing dropbox-writing thread is outstanding, so
11753            // we don't need to start it up.  The existing thread will
11754            // catch the buffer appends we just did.
11755            return;
11756        }
11757
11758        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11759        // (After this point, we shouldn't access AMS internal data structures.)
11760        new Thread("Error dump: " + dropboxTag) {
11761            @Override
11762            public void run() {
11763                // 5 second sleep to let stacks arrive and be batched together
11764                try {
11765                    Thread.sleep(5000);  // 5 seconds
11766                } catch (InterruptedException e) {}
11767
11768                String errorReport;
11769                synchronized (mStrictModeBuffer) {
11770                    errorReport = mStrictModeBuffer.toString();
11771                    if (errorReport.length() == 0) {
11772                        return;
11773                    }
11774                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11775                    mStrictModeBuffer.trimToSize();
11776                }
11777                dbox.addText(dropboxTag, errorReport);
11778            }
11779        }.start();
11780    }
11781
11782    /**
11783     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11784     * @param app object of the crashing app, null for the system server
11785     * @param tag reported by the caller
11786     * @param system whether this wtf is coming from the system
11787     * @param crashInfo describing the context of the error
11788     * @return true if the process should exit immediately (WTF is fatal)
11789     */
11790    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11791            final ApplicationErrorReport.CrashInfo crashInfo) {
11792        final int callingUid = Binder.getCallingUid();
11793        final int callingPid = Binder.getCallingPid();
11794
11795        if (system) {
11796            // If this is coming from the system, we could very well have low-level
11797            // system locks held, so we want to do this all asynchronously.  And we
11798            // never want this to become fatal, so there is that too.
11799            mHandler.post(new Runnable() {
11800                @Override public void run() {
11801                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11802                }
11803            });
11804            return false;
11805        }
11806
11807        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11808                crashInfo);
11809
11810        if (r != null && r.pid != Process.myPid() &&
11811                Settings.Global.getInt(mContext.getContentResolver(),
11812                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11813            crashApplication(r, crashInfo);
11814            return true;
11815        } else {
11816            return false;
11817        }
11818    }
11819
11820    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11821            final ApplicationErrorReport.CrashInfo crashInfo) {
11822        final ProcessRecord r = findAppProcess(app, "WTF");
11823        final String processName = app == null ? "system_server"
11824                : (r == null ? "unknown" : r.processName);
11825
11826        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11827                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11828
11829        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11830
11831        return r;
11832    }
11833
11834    /**
11835     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11836     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11837     */
11838    private ProcessRecord findAppProcess(IBinder app, String reason) {
11839        if (app == null) {
11840            return null;
11841        }
11842
11843        synchronized (this) {
11844            final int NP = mProcessNames.getMap().size();
11845            for (int ip=0; ip<NP; ip++) {
11846                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11847                final int NA = apps.size();
11848                for (int ia=0; ia<NA; ia++) {
11849                    ProcessRecord p = apps.valueAt(ia);
11850                    if (p.thread != null && p.thread.asBinder() == app) {
11851                        return p;
11852                    }
11853                }
11854            }
11855
11856            Slog.w(TAG, "Can't find mystery application for " + reason
11857                    + " from pid=" + Binder.getCallingPid()
11858                    + " uid=" + Binder.getCallingUid() + ": " + app);
11859            return null;
11860        }
11861    }
11862
11863    /**
11864     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11865     * to append various headers to the dropbox log text.
11866     */
11867    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11868            StringBuilder sb) {
11869        // Watchdog thread ends up invoking this function (with
11870        // a null ProcessRecord) to add the stack file to dropbox.
11871        // Do not acquire a lock on this (am) in such cases, as it
11872        // could cause a potential deadlock, if and when watchdog
11873        // is invoked due to unavailability of lock on am and it
11874        // would prevent watchdog from killing system_server.
11875        if (process == null) {
11876            sb.append("Process: ").append(processName).append("\n");
11877            return;
11878        }
11879        // Note: ProcessRecord 'process' is guarded by the service
11880        // instance.  (notably process.pkgList, which could otherwise change
11881        // concurrently during execution of this method)
11882        synchronized (this) {
11883            sb.append("Process: ").append(processName).append("\n");
11884            int flags = process.info.flags;
11885            IPackageManager pm = AppGlobals.getPackageManager();
11886            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11887            for (int ip=0; ip<process.pkgList.size(); ip++) {
11888                String pkg = process.pkgList.keyAt(ip);
11889                sb.append("Package: ").append(pkg);
11890                try {
11891                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11892                    if (pi != null) {
11893                        sb.append(" v").append(pi.versionCode);
11894                        if (pi.versionName != null) {
11895                            sb.append(" (").append(pi.versionName).append(")");
11896                        }
11897                    }
11898                } catch (RemoteException e) {
11899                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11900                }
11901                sb.append("\n");
11902            }
11903        }
11904    }
11905
11906    private static String processClass(ProcessRecord process) {
11907        if (process == null || process.pid == MY_PID) {
11908            return "system_server";
11909        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11910            return "system_app";
11911        } else {
11912            return "data_app";
11913        }
11914    }
11915
11916    /**
11917     * Write a description of an error (crash, WTF, ANR) to the drop box.
11918     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11919     * @param process which caused the error, null means the system server
11920     * @param activity which triggered the error, null if unknown
11921     * @param parent activity related to the error, null if unknown
11922     * @param subject line related to the error, null if absent
11923     * @param report in long form describing the error, null if absent
11924     * @param logFile to include in the report, null if none
11925     * @param crashInfo giving an application stack trace, null if absent
11926     */
11927    public void addErrorToDropBox(String eventType,
11928            ProcessRecord process, String processName, ActivityRecord activity,
11929            ActivityRecord parent, String subject,
11930            final String report, final File logFile,
11931            final ApplicationErrorReport.CrashInfo crashInfo) {
11932        // NOTE -- this must never acquire the ActivityManagerService lock,
11933        // otherwise the watchdog may be prevented from resetting the system.
11934
11935        final String dropboxTag = processClass(process) + "_" + eventType;
11936        final DropBoxManager dbox = (DropBoxManager)
11937                mContext.getSystemService(Context.DROPBOX_SERVICE);
11938
11939        // Exit early if the dropbox isn't configured to accept this report type.
11940        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11941
11942        final StringBuilder sb = new StringBuilder(1024);
11943        appendDropBoxProcessHeaders(process, processName, sb);
11944        if (activity != null) {
11945            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11946        }
11947        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11948            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11949        }
11950        if (parent != null && parent != activity) {
11951            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11952        }
11953        if (subject != null) {
11954            sb.append("Subject: ").append(subject).append("\n");
11955        }
11956        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11957        if (Debug.isDebuggerConnected()) {
11958            sb.append("Debugger: Connected\n");
11959        }
11960        sb.append("\n");
11961
11962        // Do the rest in a worker thread to avoid blocking the caller on I/O
11963        // (After this point, we shouldn't access AMS internal data structures.)
11964        Thread worker = new Thread("Error dump: " + dropboxTag) {
11965            @Override
11966            public void run() {
11967                if (report != null) {
11968                    sb.append(report);
11969                }
11970                if (logFile != null) {
11971                    try {
11972                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11973                                    "\n\n[[TRUNCATED]]"));
11974                    } catch (IOException e) {
11975                        Slog.e(TAG, "Error reading " + logFile, e);
11976                    }
11977                }
11978                if (crashInfo != null && crashInfo.stackTrace != null) {
11979                    sb.append(crashInfo.stackTrace);
11980                }
11981
11982                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11983                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11984                if (lines > 0) {
11985                    sb.append("\n");
11986
11987                    // Merge several logcat streams, and take the last N lines
11988                    InputStreamReader input = null;
11989                    try {
11990                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11991                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11992                                "-b", "crash",
11993                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11994
11995                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11996                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11997                        input = new InputStreamReader(logcat.getInputStream());
11998
11999                        int num;
12000                        char[] buf = new char[8192];
12001                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12002                    } catch (IOException e) {
12003                        Slog.e(TAG, "Error running logcat", e);
12004                    } finally {
12005                        if (input != null) try { input.close(); } catch (IOException e) {}
12006                    }
12007                }
12008
12009                dbox.addText(dropboxTag, sb.toString());
12010            }
12011        };
12012
12013        if (process == null) {
12014            // If process is null, we are being called from some internal code
12015            // and may be about to die -- run this synchronously.
12016            worker.run();
12017        } else {
12018            worker.start();
12019        }
12020    }
12021
12022    /**
12023     * Bring up the "unexpected error" dialog box for a crashing app.
12024     * Deal with edge cases (intercepts from instrumented applications,
12025     * ActivityController, error intent receivers, that sort of thing).
12026     * @param r the application crashing
12027     * @param crashInfo describing the failure
12028     */
12029    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12030        long timeMillis = System.currentTimeMillis();
12031        String shortMsg = crashInfo.exceptionClassName;
12032        String longMsg = crashInfo.exceptionMessage;
12033        String stackTrace = crashInfo.stackTrace;
12034        if (shortMsg != null && longMsg != null) {
12035            longMsg = shortMsg + ": " + longMsg;
12036        } else if (shortMsg != null) {
12037            longMsg = shortMsg;
12038        }
12039
12040        AppErrorResult result = new AppErrorResult();
12041        synchronized (this) {
12042            if (mController != null) {
12043                try {
12044                    String name = r != null ? r.processName : null;
12045                    int pid = r != null ? r.pid : Binder.getCallingPid();
12046                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12047                    if (!mController.appCrashed(name, pid,
12048                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12049                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12050                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12051                            Slog.w(TAG, "Skip killing native crashed app " + name
12052                                    + "(" + pid + ") during testing");
12053                        } else {
12054                            Slog.w(TAG, "Force-killing crashed app " + name
12055                                    + " at watcher's request");
12056                            if (r != null) {
12057                                r.kill("crash", true);
12058                            } else {
12059                                // Huh.
12060                                Process.killProcess(pid);
12061                                Process.killProcessGroup(uid, pid);
12062                            }
12063                        }
12064                        return;
12065                    }
12066                } catch (RemoteException e) {
12067                    mController = null;
12068                    Watchdog.getInstance().setActivityController(null);
12069                }
12070            }
12071
12072            final long origId = Binder.clearCallingIdentity();
12073
12074            // If this process is running instrumentation, finish it.
12075            if (r != null && r.instrumentationClass != null) {
12076                Slog.w(TAG, "Error in app " + r.processName
12077                      + " running instrumentation " + r.instrumentationClass + ":");
12078                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12079                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12080                Bundle info = new Bundle();
12081                info.putString("shortMsg", shortMsg);
12082                info.putString("longMsg", longMsg);
12083                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12084                Binder.restoreCallingIdentity(origId);
12085                return;
12086            }
12087
12088            // If we can't identify the process or it's already exceeded its crash quota,
12089            // quit right away without showing a crash dialog.
12090            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12091                Binder.restoreCallingIdentity(origId);
12092                return;
12093            }
12094
12095            Message msg = Message.obtain();
12096            msg.what = SHOW_ERROR_MSG;
12097            HashMap data = new HashMap();
12098            data.put("result", result);
12099            data.put("app", r);
12100            msg.obj = data;
12101            mHandler.sendMessage(msg);
12102
12103            Binder.restoreCallingIdentity(origId);
12104        }
12105
12106        int res = result.get();
12107
12108        Intent appErrorIntent = null;
12109        synchronized (this) {
12110            if (r != null && !r.isolated) {
12111                // XXX Can't keep track of crash time for isolated processes,
12112                // since they don't have a persistent identity.
12113                mProcessCrashTimes.put(r.info.processName, r.uid,
12114                        SystemClock.uptimeMillis());
12115            }
12116            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12117                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12118            }
12119        }
12120
12121        if (appErrorIntent != null) {
12122            try {
12123                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12124            } catch (ActivityNotFoundException e) {
12125                Slog.w(TAG, "bug report receiver dissappeared", e);
12126            }
12127        }
12128    }
12129
12130    Intent createAppErrorIntentLocked(ProcessRecord r,
12131            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12132        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12133        if (report == null) {
12134            return null;
12135        }
12136        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12137        result.setComponent(r.errorReportReceiver);
12138        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12139        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12140        return result;
12141    }
12142
12143    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12144            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12145        if (r.errorReportReceiver == null) {
12146            return null;
12147        }
12148
12149        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12150            return null;
12151        }
12152
12153        ApplicationErrorReport report = new ApplicationErrorReport();
12154        report.packageName = r.info.packageName;
12155        report.installerPackageName = r.errorReportReceiver.getPackageName();
12156        report.processName = r.processName;
12157        report.time = timeMillis;
12158        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12159
12160        if (r.crashing || r.forceCrashReport) {
12161            report.type = ApplicationErrorReport.TYPE_CRASH;
12162            report.crashInfo = crashInfo;
12163        } else if (r.notResponding) {
12164            report.type = ApplicationErrorReport.TYPE_ANR;
12165            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12166
12167            report.anrInfo.activity = r.notRespondingReport.tag;
12168            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12169            report.anrInfo.info = r.notRespondingReport.longMsg;
12170        }
12171
12172        return report;
12173    }
12174
12175    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12176        enforceNotIsolatedCaller("getProcessesInErrorState");
12177        // assume our apps are happy - lazy create the list
12178        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12179
12180        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12181                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12182        int userId = UserHandle.getUserId(Binder.getCallingUid());
12183
12184        synchronized (this) {
12185
12186            // iterate across all processes
12187            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12188                ProcessRecord app = mLruProcesses.get(i);
12189                if (!allUsers && app.userId != userId) {
12190                    continue;
12191                }
12192                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12193                    // This one's in trouble, so we'll generate a report for it
12194                    // crashes are higher priority (in case there's a crash *and* an anr)
12195                    ActivityManager.ProcessErrorStateInfo report = null;
12196                    if (app.crashing) {
12197                        report = app.crashingReport;
12198                    } else if (app.notResponding) {
12199                        report = app.notRespondingReport;
12200                    }
12201
12202                    if (report != null) {
12203                        if (errList == null) {
12204                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12205                        }
12206                        errList.add(report);
12207                    } else {
12208                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12209                                " crashing = " + app.crashing +
12210                                " notResponding = " + app.notResponding);
12211                    }
12212                }
12213            }
12214        }
12215
12216        return errList;
12217    }
12218
12219    static int procStateToImportance(int procState, int memAdj,
12220            ActivityManager.RunningAppProcessInfo currApp) {
12221        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12222        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12223            currApp.lru = memAdj;
12224        } else {
12225            currApp.lru = 0;
12226        }
12227        return imp;
12228    }
12229
12230    private void fillInProcMemInfo(ProcessRecord app,
12231            ActivityManager.RunningAppProcessInfo outInfo) {
12232        outInfo.pid = app.pid;
12233        outInfo.uid = app.info.uid;
12234        if (mHeavyWeightProcess == app) {
12235            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12236        }
12237        if (app.persistent) {
12238            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12239        }
12240        if (app.activities.size() > 0) {
12241            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12242        }
12243        outInfo.lastTrimLevel = app.trimMemoryLevel;
12244        int adj = app.curAdj;
12245        int procState = app.curProcState;
12246        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12247        outInfo.importanceReasonCode = app.adjTypeCode;
12248        outInfo.processState = app.curProcState;
12249    }
12250
12251    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12252        enforceNotIsolatedCaller("getRunningAppProcesses");
12253        // Lazy instantiation of list
12254        List<ActivityManager.RunningAppProcessInfo> runList = null;
12255        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12256                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12257        int userId = UserHandle.getUserId(Binder.getCallingUid());
12258        synchronized (this) {
12259            // Iterate across all processes
12260            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12261                ProcessRecord app = mLruProcesses.get(i);
12262                if (!allUsers && app.userId != userId) {
12263                    continue;
12264                }
12265                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12266                    // Generate process state info for running application
12267                    ActivityManager.RunningAppProcessInfo currApp =
12268                        new ActivityManager.RunningAppProcessInfo(app.processName,
12269                                app.pid, app.getPackageList());
12270                    fillInProcMemInfo(app, currApp);
12271                    if (app.adjSource instanceof ProcessRecord) {
12272                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12273                        currApp.importanceReasonImportance =
12274                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12275                                        app.adjSourceProcState);
12276                    } else if (app.adjSource instanceof ActivityRecord) {
12277                        ActivityRecord r = (ActivityRecord)app.adjSource;
12278                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12279                    }
12280                    if (app.adjTarget instanceof ComponentName) {
12281                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12282                    }
12283                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12284                    //        + " lru=" + currApp.lru);
12285                    if (runList == null) {
12286                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12287                    }
12288                    runList.add(currApp);
12289                }
12290            }
12291        }
12292        return runList;
12293    }
12294
12295    public List<ApplicationInfo> getRunningExternalApplications() {
12296        enforceNotIsolatedCaller("getRunningExternalApplications");
12297        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12298        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12299        if (runningApps != null && runningApps.size() > 0) {
12300            Set<String> extList = new HashSet<String>();
12301            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12302                if (app.pkgList != null) {
12303                    for (String pkg : app.pkgList) {
12304                        extList.add(pkg);
12305                    }
12306                }
12307            }
12308            IPackageManager pm = AppGlobals.getPackageManager();
12309            for (String pkg : extList) {
12310                try {
12311                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12312                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12313                        retList.add(info);
12314                    }
12315                } catch (RemoteException e) {
12316                }
12317            }
12318        }
12319        return retList;
12320    }
12321
12322    @Override
12323    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12324        enforceNotIsolatedCaller("getMyMemoryState");
12325        synchronized (this) {
12326            ProcessRecord proc;
12327            synchronized (mPidsSelfLocked) {
12328                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12329            }
12330            fillInProcMemInfo(proc, outInfo);
12331        }
12332    }
12333
12334    @Override
12335    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12336        if (checkCallingPermission(android.Manifest.permission.DUMP)
12337                != PackageManager.PERMISSION_GRANTED) {
12338            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12339                    + Binder.getCallingPid()
12340                    + ", uid=" + Binder.getCallingUid()
12341                    + " without permission "
12342                    + android.Manifest.permission.DUMP);
12343            return;
12344        }
12345
12346        boolean dumpAll = false;
12347        boolean dumpClient = false;
12348        String dumpPackage = null;
12349
12350        int opti = 0;
12351        while (opti < args.length) {
12352            String opt = args[opti];
12353            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12354                break;
12355            }
12356            opti++;
12357            if ("-a".equals(opt)) {
12358                dumpAll = true;
12359            } else if ("-c".equals(opt)) {
12360                dumpClient = true;
12361            } else if ("-h".equals(opt)) {
12362                pw.println("Activity manager dump options:");
12363                pw.println("  [-a] [-c] [-h] [cmd] ...");
12364                pw.println("  cmd may be one of:");
12365                pw.println("    a[ctivities]: activity stack state");
12366                pw.println("    r[recents]: recent activities state");
12367                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12368                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12369                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12370                pw.println("    o[om]: out of memory management");
12371                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12372                pw.println("    provider [COMP_SPEC]: provider client-side state");
12373                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12374                pw.println("    service [COMP_SPEC]: service client-side state");
12375                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12376                pw.println("    all: dump all activities");
12377                pw.println("    top: dump the top activity");
12378                pw.println("    write: write all pending state to storage");
12379                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12380                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12381                pw.println("    a partial substring in a component name, a");
12382                pw.println("    hex object identifier.");
12383                pw.println("  -a: include all available server state.");
12384                pw.println("  -c: include client state.");
12385                return;
12386            } else {
12387                pw.println("Unknown argument: " + opt + "; use -h for help");
12388            }
12389        }
12390
12391        long origId = Binder.clearCallingIdentity();
12392        boolean more = false;
12393        // Is the caller requesting to dump a particular piece of data?
12394        if (opti < args.length) {
12395            String cmd = args[opti];
12396            opti++;
12397            if ("activities".equals(cmd) || "a".equals(cmd)) {
12398                synchronized (this) {
12399                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12400                }
12401            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12402                synchronized (this) {
12403                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12404                }
12405            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12406                String[] newArgs;
12407                String name;
12408                if (opti >= args.length) {
12409                    name = null;
12410                    newArgs = EMPTY_STRING_ARRAY;
12411                } else {
12412                    name = args[opti];
12413                    opti++;
12414                    newArgs = new String[args.length - opti];
12415                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12416                            args.length - opti);
12417                }
12418                synchronized (this) {
12419                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12420                }
12421            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12422                String[] newArgs;
12423                String name;
12424                if (opti >= args.length) {
12425                    name = null;
12426                    newArgs = EMPTY_STRING_ARRAY;
12427                } else {
12428                    name = args[opti];
12429                    opti++;
12430                    newArgs = new String[args.length - opti];
12431                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12432                            args.length - opti);
12433                }
12434                synchronized (this) {
12435                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12436                }
12437            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12438                String[] newArgs;
12439                String name;
12440                if (opti >= args.length) {
12441                    name = null;
12442                    newArgs = EMPTY_STRING_ARRAY;
12443                } else {
12444                    name = args[opti];
12445                    opti++;
12446                    newArgs = new String[args.length - opti];
12447                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12448                            args.length - opti);
12449                }
12450                synchronized (this) {
12451                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12452                }
12453            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12454                synchronized (this) {
12455                    dumpOomLocked(fd, pw, args, opti, true);
12456                }
12457            } else if ("provider".equals(cmd)) {
12458                String[] newArgs;
12459                String name;
12460                if (opti >= args.length) {
12461                    name = null;
12462                    newArgs = EMPTY_STRING_ARRAY;
12463                } else {
12464                    name = args[opti];
12465                    opti++;
12466                    newArgs = new String[args.length - opti];
12467                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12468                }
12469                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12470                    pw.println("No providers match: " + name);
12471                    pw.println("Use -h for help.");
12472                }
12473            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12474                synchronized (this) {
12475                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12476                }
12477            } else if ("service".equals(cmd)) {
12478                String[] newArgs;
12479                String name;
12480                if (opti >= args.length) {
12481                    name = null;
12482                    newArgs = EMPTY_STRING_ARRAY;
12483                } else {
12484                    name = args[opti];
12485                    opti++;
12486                    newArgs = new String[args.length - opti];
12487                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12488                            args.length - opti);
12489                }
12490                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12491                    pw.println("No services match: " + name);
12492                    pw.println("Use -h for help.");
12493                }
12494            } else if ("package".equals(cmd)) {
12495                String[] newArgs;
12496                if (opti >= args.length) {
12497                    pw.println("package: no package name specified");
12498                    pw.println("Use -h for help.");
12499                } else {
12500                    dumpPackage = args[opti];
12501                    opti++;
12502                    newArgs = new String[args.length - opti];
12503                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12504                            args.length - opti);
12505                    args = newArgs;
12506                    opti = 0;
12507                    more = true;
12508                }
12509            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12510                synchronized (this) {
12511                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12512                }
12513            } else if ("write".equals(cmd)) {
12514                mTaskPersister.flush();
12515                pw.println("All tasks persisted.");
12516                return;
12517            } else {
12518                // Dumping a single activity?
12519                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12520                    pw.println("Bad activity command, or no activities match: " + cmd);
12521                    pw.println("Use -h for help.");
12522                }
12523            }
12524            if (!more) {
12525                Binder.restoreCallingIdentity(origId);
12526                return;
12527            }
12528        }
12529
12530        // No piece of data specified, dump everything.
12531        synchronized (this) {
12532            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12533            pw.println();
12534            if (dumpAll) {
12535                pw.println("-------------------------------------------------------------------------------");
12536            }
12537            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12538            pw.println();
12539            if (dumpAll) {
12540                pw.println("-------------------------------------------------------------------------------");
12541            }
12542            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12543            pw.println();
12544            if (dumpAll) {
12545                pw.println("-------------------------------------------------------------------------------");
12546            }
12547            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12548            pw.println();
12549            if (dumpAll) {
12550                pw.println("-------------------------------------------------------------------------------");
12551            }
12552            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12553            pw.println();
12554            if (dumpAll) {
12555                pw.println("-------------------------------------------------------------------------------");
12556            }
12557            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12558            pw.println();
12559            if (dumpAll) {
12560                pw.println("-------------------------------------------------------------------------------");
12561            }
12562            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12563        }
12564        Binder.restoreCallingIdentity(origId);
12565    }
12566
12567    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12568            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12569        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12570
12571        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12572                dumpPackage);
12573        boolean needSep = printedAnything;
12574
12575        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12576                dumpPackage, needSep, "  mFocusedActivity: ");
12577        if (printed) {
12578            printedAnything = true;
12579            needSep = false;
12580        }
12581
12582        if (dumpPackage == null) {
12583            if (needSep) {
12584                pw.println();
12585            }
12586            needSep = true;
12587            printedAnything = true;
12588            mStackSupervisor.dump(pw, "  ");
12589        }
12590
12591        if (!printedAnything) {
12592            pw.println("  (nothing)");
12593        }
12594    }
12595
12596    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12597            int opti, boolean dumpAll, String dumpPackage) {
12598        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12599
12600        boolean printedAnything = false;
12601
12602        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12603            boolean printedHeader = false;
12604
12605            final int N = mRecentTasks.size();
12606            for (int i=0; i<N; i++) {
12607                TaskRecord tr = mRecentTasks.get(i);
12608                if (dumpPackage != null) {
12609                    if (tr.realActivity == null ||
12610                            !dumpPackage.equals(tr.realActivity)) {
12611                        continue;
12612                    }
12613                }
12614                if (!printedHeader) {
12615                    pw.println("  Recent tasks:");
12616                    printedHeader = true;
12617                    printedAnything = true;
12618                }
12619                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12620                        pw.println(tr);
12621                if (dumpAll) {
12622                    mRecentTasks.get(i).dump(pw, "    ");
12623                }
12624            }
12625        }
12626
12627        if (!printedAnything) {
12628            pw.println("  (nothing)");
12629        }
12630    }
12631
12632    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12633            int opti, boolean dumpAll, String dumpPackage) {
12634        boolean needSep = false;
12635        boolean printedAnything = false;
12636        int numPers = 0;
12637
12638        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12639
12640        if (dumpAll) {
12641            final int NP = mProcessNames.getMap().size();
12642            for (int ip=0; ip<NP; ip++) {
12643                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12644                final int NA = procs.size();
12645                for (int ia=0; ia<NA; ia++) {
12646                    ProcessRecord r = procs.valueAt(ia);
12647                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12648                        continue;
12649                    }
12650                    if (!needSep) {
12651                        pw.println("  All known processes:");
12652                        needSep = true;
12653                        printedAnything = true;
12654                    }
12655                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12656                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12657                        pw.print(" "); pw.println(r);
12658                    r.dump(pw, "    ");
12659                    if (r.persistent) {
12660                        numPers++;
12661                    }
12662                }
12663            }
12664        }
12665
12666        if (mIsolatedProcesses.size() > 0) {
12667            boolean printed = false;
12668            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12669                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12670                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12671                    continue;
12672                }
12673                if (!printed) {
12674                    if (needSep) {
12675                        pw.println();
12676                    }
12677                    pw.println("  Isolated process list (sorted by uid):");
12678                    printedAnything = true;
12679                    printed = true;
12680                    needSep = true;
12681                }
12682                pw.println(String.format("%sIsolated #%2d: %s",
12683                        "    ", i, r.toString()));
12684            }
12685        }
12686
12687        if (mLruProcesses.size() > 0) {
12688            if (needSep) {
12689                pw.println();
12690            }
12691            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12692                    pw.print(" total, non-act at ");
12693                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12694                    pw.print(", non-svc at ");
12695                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12696                    pw.println("):");
12697            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12698            needSep = true;
12699            printedAnything = true;
12700        }
12701
12702        if (dumpAll || dumpPackage != null) {
12703            synchronized (mPidsSelfLocked) {
12704                boolean printed = false;
12705                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12706                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12707                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12708                        continue;
12709                    }
12710                    if (!printed) {
12711                        if (needSep) pw.println();
12712                        needSep = true;
12713                        pw.println("  PID mappings:");
12714                        printed = true;
12715                        printedAnything = true;
12716                    }
12717                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12718                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12719                }
12720            }
12721        }
12722
12723        if (mForegroundProcesses.size() > 0) {
12724            synchronized (mPidsSelfLocked) {
12725                boolean printed = false;
12726                for (int i=0; i<mForegroundProcesses.size(); i++) {
12727                    ProcessRecord r = mPidsSelfLocked.get(
12728                            mForegroundProcesses.valueAt(i).pid);
12729                    if (dumpPackage != null && (r == null
12730                            || !r.pkgList.containsKey(dumpPackage))) {
12731                        continue;
12732                    }
12733                    if (!printed) {
12734                        if (needSep) pw.println();
12735                        needSep = true;
12736                        pw.println("  Foreground Processes:");
12737                        printed = true;
12738                        printedAnything = true;
12739                    }
12740                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12741                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12742                }
12743            }
12744        }
12745
12746        if (mPersistentStartingProcesses.size() > 0) {
12747            if (needSep) pw.println();
12748            needSep = true;
12749            printedAnything = true;
12750            pw.println("  Persisent processes that are starting:");
12751            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12752                    "Starting Norm", "Restarting PERS", dumpPackage);
12753        }
12754
12755        if (mRemovedProcesses.size() > 0) {
12756            if (needSep) pw.println();
12757            needSep = true;
12758            printedAnything = true;
12759            pw.println("  Processes that are being removed:");
12760            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12761                    "Removed Norm", "Removed PERS", dumpPackage);
12762        }
12763
12764        if (mProcessesOnHold.size() > 0) {
12765            if (needSep) pw.println();
12766            needSep = true;
12767            printedAnything = true;
12768            pw.println("  Processes that are on old until the system is ready:");
12769            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12770                    "OnHold Norm", "OnHold PERS", dumpPackage);
12771        }
12772
12773        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12774
12775        if (mProcessCrashTimes.getMap().size() > 0) {
12776            boolean printed = false;
12777            long now = SystemClock.uptimeMillis();
12778            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12779            final int NP = pmap.size();
12780            for (int ip=0; ip<NP; ip++) {
12781                String pname = pmap.keyAt(ip);
12782                SparseArray<Long> uids = pmap.valueAt(ip);
12783                final int N = uids.size();
12784                for (int i=0; i<N; i++) {
12785                    int puid = uids.keyAt(i);
12786                    ProcessRecord r = mProcessNames.get(pname, puid);
12787                    if (dumpPackage != null && (r == null
12788                            || !r.pkgList.containsKey(dumpPackage))) {
12789                        continue;
12790                    }
12791                    if (!printed) {
12792                        if (needSep) pw.println();
12793                        needSep = true;
12794                        pw.println("  Time since processes crashed:");
12795                        printed = true;
12796                        printedAnything = true;
12797                    }
12798                    pw.print("    Process "); pw.print(pname);
12799                            pw.print(" uid "); pw.print(puid);
12800                            pw.print(": last crashed ");
12801                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12802                            pw.println(" ago");
12803                }
12804            }
12805        }
12806
12807        if (mBadProcesses.getMap().size() > 0) {
12808            boolean printed = false;
12809            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12810            final int NP = pmap.size();
12811            for (int ip=0; ip<NP; ip++) {
12812                String pname = pmap.keyAt(ip);
12813                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12814                final int N = uids.size();
12815                for (int i=0; i<N; i++) {
12816                    int puid = uids.keyAt(i);
12817                    ProcessRecord r = mProcessNames.get(pname, puid);
12818                    if (dumpPackage != null && (r == null
12819                            || !r.pkgList.containsKey(dumpPackage))) {
12820                        continue;
12821                    }
12822                    if (!printed) {
12823                        if (needSep) pw.println();
12824                        needSep = true;
12825                        pw.println("  Bad processes:");
12826                        printedAnything = true;
12827                    }
12828                    BadProcessInfo info = uids.valueAt(i);
12829                    pw.print("    Bad process "); pw.print(pname);
12830                            pw.print(" uid "); pw.print(puid);
12831                            pw.print(": crashed at time "); pw.println(info.time);
12832                    if (info.shortMsg != null) {
12833                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12834                    }
12835                    if (info.longMsg != null) {
12836                        pw.print("      Long msg: "); pw.println(info.longMsg);
12837                    }
12838                    if (info.stack != null) {
12839                        pw.println("      Stack:");
12840                        int lastPos = 0;
12841                        for (int pos=0; pos<info.stack.length(); pos++) {
12842                            if (info.stack.charAt(pos) == '\n') {
12843                                pw.print("        ");
12844                                pw.write(info.stack, lastPos, pos-lastPos);
12845                                pw.println();
12846                                lastPos = pos+1;
12847                            }
12848                        }
12849                        if (lastPos < info.stack.length()) {
12850                            pw.print("        ");
12851                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12852                            pw.println();
12853                        }
12854                    }
12855                }
12856            }
12857        }
12858
12859        if (dumpPackage == null) {
12860            pw.println();
12861            needSep = false;
12862            pw.println("  mStartedUsers:");
12863            for (int i=0; i<mStartedUsers.size(); i++) {
12864                UserStartedState uss = mStartedUsers.valueAt(i);
12865                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12866                        pw.print(": "); uss.dump("", pw);
12867            }
12868            pw.print("  mStartedUserArray: [");
12869            for (int i=0; i<mStartedUserArray.length; i++) {
12870                if (i > 0) pw.print(", ");
12871                pw.print(mStartedUserArray[i]);
12872            }
12873            pw.println("]");
12874            pw.print("  mUserLru: [");
12875            for (int i=0; i<mUserLru.size(); i++) {
12876                if (i > 0) pw.print(", ");
12877                pw.print(mUserLru.get(i));
12878            }
12879            pw.println("]");
12880            if (dumpAll) {
12881                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12882            }
12883            synchronized (mUserProfileGroupIdsSelfLocked) {
12884                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12885                    pw.println("  mUserProfileGroupIds:");
12886                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12887                        pw.print("    User #");
12888                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12889                        pw.print(" -> profile #");
12890                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12891                    }
12892                }
12893            }
12894        }
12895        if (mHomeProcess != null && (dumpPackage == null
12896                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12897            if (needSep) {
12898                pw.println();
12899                needSep = false;
12900            }
12901            pw.println("  mHomeProcess: " + mHomeProcess);
12902        }
12903        if (mPreviousProcess != null && (dumpPackage == null
12904                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12905            if (needSep) {
12906                pw.println();
12907                needSep = false;
12908            }
12909            pw.println("  mPreviousProcess: " + mPreviousProcess);
12910        }
12911        if (dumpAll) {
12912            StringBuilder sb = new StringBuilder(128);
12913            sb.append("  mPreviousProcessVisibleTime: ");
12914            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12915            pw.println(sb);
12916        }
12917        if (mHeavyWeightProcess != null && (dumpPackage == null
12918                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12919            if (needSep) {
12920                pw.println();
12921                needSep = false;
12922            }
12923            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12924        }
12925        if (dumpPackage == null) {
12926            pw.println("  mConfiguration: " + mConfiguration);
12927        }
12928        if (dumpAll) {
12929            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12930            if (mCompatModePackages.getPackages().size() > 0) {
12931                boolean printed = false;
12932                for (Map.Entry<String, Integer> entry
12933                        : mCompatModePackages.getPackages().entrySet()) {
12934                    String pkg = entry.getKey();
12935                    int mode = entry.getValue();
12936                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12937                        continue;
12938                    }
12939                    if (!printed) {
12940                        pw.println("  mScreenCompatPackages:");
12941                        printed = true;
12942                    }
12943                    pw.print("    "); pw.print(pkg); pw.print(": ");
12944                            pw.print(mode); pw.println();
12945                }
12946            }
12947        }
12948        if (dumpPackage == null) {
12949            if (mSleeping || mWentToSleep || mLockScreenShown) {
12950                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12951                        + " mLockScreenShown " + mLockScreenShown);
12952            }
12953            if (mShuttingDown || mRunningVoice) {
12954                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12955            }
12956        }
12957        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12958                || mOrigWaitForDebugger) {
12959            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12960                    || dumpPackage.equals(mOrigDebugApp)) {
12961                if (needSep) {
12962                    pw.println();
12963                    needSep = false;
12964                }
12965                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12966                        + " mDebugTransient=" + mDebugTransient
12967                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12968            }
12969        }
12970        if (mOpenGlTraceApp != null) {
12971            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12972                if (needSep) {
12973                    pw.println();
12974                    needSep = false;
12975                }
12976                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12977            }
12978        }
12979        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12980                || mProfileFd != null) {
12981            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12982                if (needSep) {
12983                    pw.println();
12984                    needSep = false;
12985                }
12986                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12987                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12988                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12989                        + mAutoStopProfiler);
12990                pw.println("  mProfileType=" + mProfileType);
12991            }
12992        }
12993        if (dumpPackage == null) {
12994            if (mAlwaysFinishActivities || mController != null) {
12995                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12996                        + " mController=" + mController);
12997            }
12998            if (dumpAll) {
12999                pw.println("  Total persistent processes: " + numPers);
13000                pw.println("  mProcessesReady=" + mProcessesReady
13001                        + " mSystemReady=" + mSystemReady
13002                        + " mBooted=" + mBooted
13003                        + " mFactoryTest=" + mFactoryTest);
13004                pw.println("  mBooting=" + mBooting
13005                        + " mCallFinishBooting=" + mCallFinishBooting
13006                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13007                pw.print("  mLastPowerCheckRealtime=");
13008                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13009                        pw.println("");
13010                pw.print("  mLastPowerCheckUptime=");
13011                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13012                        pw.println("");
13013                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13014                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13015                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13016                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13017                        + " (" + mLruProcesses.size() + " total)"
13018                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13019                        + " mNumServiceProcs=" + mNumServiceProcs
13020                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13021                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13022                        + " mLastMemoryLevel" + mLastMemoryLevel
13023                        + " mLastNumProcesses" + mLastNumProcesses);
13024                long now = SystemClock.uptimeMillis();
13025                pw.print("  mLastIdleTime=");
13026                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13027                        pw.print(" mLowRamSinceLastIdle=");
13028                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13029                        pw.println();
13030            }
13031        }
13032
13033        if (!printedAnything) {
13034            pw.println("  (nothing)");
13035        }
13036    }
13037
13038    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13039            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13040        if (mProcessesToGc.size() > 0) {
13041            boolean printed = false;
13042            long now = SystemClock.uptimeMillis();
13043            for (int i=0; i<mProcessesToGc.size(); i++) {
13044                ProcessRecord proc = mProcessesToGc.get(i);
13045                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13046                    continue;
13047                }
13048                if (!printed) {
13049                    if (needSep) pw.println();
13050                    needSep = true;
13051                    pw.println("  Processes that are waiting to GC:");
13052                    printed = true;
13053                }
13054                pw.print("    Process "); pw.println(proc);
13055                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13056                        pw.print(", last gced=");
13057                        pw.print(now-proc.lastRequestedGc);
13058                        pw.print(" ms ago, last lowMem=");
13059                        pw.print(now-proc.lastLowMemory);
13060                        pw.println(" ms ago");
13061
13062            }
13063        }
13064        return needSep;
13065    }
13066
13067    void printOomLevel(PrintWriter pw, String name, int adj) {
13068        pw.print("    ");
13069        if (adj >= 0) {
13070            pw.print(' ');
13071            if (adj < 10) pw.print(' ');
13072        } else {
13073            if (adj > -10) pw.print(' ');
13074        }
13075        pw.print(adj);
13076        pw.print(": ");
13077        pw.print(name);
13078        pw.print(" (");
13079        pw.print(mProcessList.getMemLevel(adj)/1024);
13080        pw.println(" kB)");
13081    }
13082
13083    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13084            int opti, boolean dumpAll) {
13085        boolean needSep = false;
13086
13087        if (mLruProcesses.size() > 0) {
13088            if (needSep) pw.println();
13089            needSep = true;
13090            pw.println("  OOM levels:");
13091            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13092            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13093            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13094            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13095            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13096            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13097            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13098            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13099            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13100            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13101            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13102            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13103            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13104            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13105
13106            if (needSep) pw.println();
13107            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13108                    pw.print(" total, non-act at ");
13109                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13110                    pw.print(", non-svc at ");
13111                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13112                    pw.println("):");
13113            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13114            needSep = true;
13115        }
13116
13117        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13118
13119        pw.println();
13120        pw.println("  mHomeProcess: " + mHomeProcess);
13121        pw.println("  mPreviousProcess: " + mPreviousProcess);
13122        if (mHeavyWeightProcess != null) {
13123            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13124        }
13125
13126        return true;
13127    }
13128
13129    /**
13130     * There are three ways to call this:
13131     *  - no provider specified: dump all the providers
13132     *  - a flattened component name that matched an existing provider was specified as the
13133     *    first arg: dump that one provider
13134     *  - the first arg isn't the flattened component name of an existing provider:
13135     *    dump all providers whose component contains the first arg as a substring
13136     */
13137    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13138            int opti, boolean dumpAll) {
13139        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13140    }
13141
13142    static class ItemMatcher {
13143        ArrayList<ComponentName> components;
13144        ArrayList<String> strings;
13145        ArrayList<Integer> objects;
13146        boolean all;
13147
13148        ItemMatcher() {
13149            all = true;
13150        }
13151
13152        void build(String name) {
13153            ComponentName componentName = ComponentName.unflattenFromString(name);
13154            if (componentName != null) {
13155                if (components == null) {
13156                    components = new ArrayList<ComponentName>();
13157                }
13158                components.add(componentName);
13159                all = false;
13160            } else {
13161                int objectId = 0;
13162                // Not a '/' separated full component name; maybe an object ID?
13163                try {
13164                    objectId = Integer.parseInt(name, 16);
13165                    if (objects == null) {
13166                        objects = new ArrayList<Integer>();
13167                    }
13168                    objects.add(objectId);
13169                    all = false;
13170                } catch (RuntimeException e) {
13171                    // Not an integer; just do string match.
13172                    if (strings == null) {
13173                        strings = new ArrayList<String>();
13174                    }
13175                    strings.add(name);
13176                    all = false;
13177                }
13178            }
13179        }
13180
13181        int build(String[] args, int opti) {
13182            for (; opti<args.length; opti++) {
13183                String name = args[opti];
13184                if ("--".equals(name)) {
13185                    return opti+1;
13186                }
13187                build(name);
13188            }
13189            return opti;
13190        }
13191
13192        boolean match(Object object, ComponentName comp) {
13193            if (all) {
13194                return true;
13195            }
13196            if (components != null) {
13197                for (int i=0; i<components.size(); i++) {
13198                    if (components.get(i).equals(comp)) {
13199                        return true;
13200                    }
13201                }
13202            }
13203            if (objects != null) {
13204                for (int i=0; i<objects.size(); i++) {
13205                    if (System.identityHashCode(object) == objects.get(i)) {
13206                        return true;
13207                    }
13208                }
13209            }
13210            if (strings != null) {
13211                String flat = comp.flattenToString();
13212                for (int i=0; i<strings.size(); i++) {
13213                    if (flat.contains(strings.get(i))) {
13214                        return true;
13215                    }
13216                }
13217            }
13218            return false;
13219        }
13220    }
13221
13222    /**
13223     * There are three things that cmd can be:
13224     *  - a flattened component name that matches an existing activity
13225     *  - the cmd arg isn't the flattened component name of an existing activity:
13226     *    dump all activity whose component contains the cmd as a substring
13227     *  - A hex number of the ActivityRecord object instance.
13228     */
13229    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13230            int opti, boolean dumpAll) {
13231        ArrayList<ActivityRecord> activities;
13232
13233        synchronized (this) {
13234            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13235        }
13236
13237        if (activities.size() <= 0) {
13238            return false;
13239        }
13240
13241        String[] newArgs = new String[args.length - opti];
13242        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13243
13244        TaskRecord lastTask = null;
13245        boolean needSep = false;
13246        for (int i=activities.size()-1; i>=0; i--) {
13247            ActivityRecord r = activities.get(i);
13248            if (needSep) {
13249                pw.println();
13250            }
13251            needSep = true;
13252            synchronized (this) {
13253                if (lastTask != r.task) {
13254                    lastTask = r.task;
13255                    pw.print("TASK "); pw.print(lastTask.affinity);
13256                            pw.print(" id="); pw.println(lastTask.taskId);
13257                    if (dumpAll) {
13258                        lastTask.dump(pw, "  ");
13259                    }
13260                }
13261            }
13262            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13263        }
13264        return true;
13265    }
13266
13267    /**
13268     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13269     * there is a thread associated with the activity.
13270     */
13271    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13272            final ActivityRecord r, String[] args, boolean dumpAll) {
13273        String innerPrefix = prefix + "  ";
13274        synchronized (this) {
13275            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13276                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13277                    pw.print(" pid=");
13278                    if (r.app != null) pw.println(r.app.pid);
13279                    else pw.println("(not running)");
13280            if (dumpAll) {
13281                r.dump(pw, innerPrefix);
13282            }
13283        }
13284        if (r.app != null && r.app.thread != null) {
13285            // flush anything that is already in the PrintWriter since the thread is going
13286            // to write to the file descriptor directly
13287            pw.flush();
13288            try {
13289                TransferPipe tp = new TransferPipe();
13290                try {
13291                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13292                            r.appToken, innerPrefix, args);
13293                    tp.go(fd);
13294                } finally {
13295                    tp.kill();
13296                }
13297            } catch (IOException e) {
13298                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13299            } catch (RemoteException e) {
13300                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13301            }
13302        }
13303    }
13304
13305    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13306            int opti, boolean dumpAll, String dumpPackage) {
13307        boolean needSep = false;
13308        boolean onlyHistory = false;
13309        boolean printedAnything = false;
13310
13311        if ("history".equals(dumpPackage)) {
13312            if (opti < args.length && "-s".equals(args[opti])) {
13313                dumpAll = false;
13314            }
13315            onlyHistory = true;
13316            dumpPackage = null;
13317        }
13318
13319        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13320        if (!onlyHistory && dumpAll) {
13321            if (mRegisteredReceivers.size() > 0) {
13322                boolean printed = false;
13323                Iterator it = mRegisteredReceivers.values().iterator();
13324                while (it.hasNext()) {
13325                    ReceiverList r = (ReceiverList)it.next();
13326                    if (dumpPackage != null && (r.app == null ||
13327                            !dumpPackage.equals(r.app.info.packageName))) {
13328                        continue;
13329                    }
13330                    if (!printed) {
13331                        pw.println("  Registered Receivers:");
13332                        needSep = true;
13333                        printed = true;
13334                        printedAnything = true;
13335                    }
13336                    pw.print("  * "); pw.println(r);
13337                    r.dump(pw, "    ");
13338                }
13339            }
13340
13341            if (mReceiverResolver.dump(pw, needSep ?
13342                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13343                    "    ", dumpPackage, false)) {
13344                needSep = true;
13345                printedAnything = true;
13346            }
13347        }
13348
13349        for (BroadcastQueue q : mBroadcastQueues) {
13350            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13351            printedAnything |= needSep;
13352        }
13353
13354        needSep = true;
13355
13356        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13357            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13358                if (needSep) {
13359                    pw.println();
13360                }
13361                needSep = true;
13362                printedAnything = true;
13363                pw.print("  Sticky broadcasts for user ");
13364                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13365                StringBuilder sb = new StringBuilder(128);
13366                for (Map.Entry<String, ArrayList<Intent>> ent
13367                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13368                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13369                    if (dumpAll) {
13370                        pw.println(":");
13371                        ArrayList<Intent> intents = ent.getValue();
13372                        final int N = intents.size();
13373                        for (int i=0; i<N; i++) {
13374                            sb.setLength(0);
13375                            sb.append("    Intent: ");
13376                            intents.get(i).toShortString(sb, false, true, false, false);
13377                            pw.println(sb.toString());
13378                            Bundle bundle = intents.get(i).getExtras();
13379                            if (bundle != null) {
13380                                pw.print("      ");
13381                                pw.println(bundle.toString());
13382                            }
13383                        }
13384                    } else {
13385                        pw.println("");
13386                    }
13387                }
13388            }
13389        }
13390
13391        if (!onlyHistory && dumpAll) {
13392            pw.println();
13393            for (BroadcastQueue queue : mBroadcastQueues) {
13394                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13395                        + queue.mBroadcastsScheduled);
13396            }
13397            pw.println("  mHandler:");
13398            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13399            needSep = true;
13400            printedAnything = true;
13401        }
13402
13403        if (!printedAnything) {
13404            pw.println("  (nothing)");
13405        }
13406    }
13407
13408    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13409            int opti, boolean dumpAll, String dumpPackage) {
13410        boolean needSep;
13411        boolean printedAnything = false;
13412
13413        ItemMatcher matcher = new ItemMatcher();
13414        matcher.build(args, opti);
13415
13416        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13417
13418        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13419        printedAnything |= needSep;
13420
13421        if (mLaunchingProviders.size() > 0) {
13422            boolean printed = false;
13423            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13424                ContentProviderRecord r = mLaunchingProviders.get(i);
13425                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13426                    continue;
13427                }
13428                if (!printed) {
13429                    if (needSep) pw.println();
13430                    needSep = true;
13431                    pw.println("  Launching content providers:");
13432                    printed = true;
13433                    printedAnything = true;
13434                }
13435                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13436                        pw.println(r);
13437            }
13438        }
13439
13440        if (mGrantedUriPermissions.size() > 0) {
13441            boolean printed = false;
13442            int dumpUid = -2;
13443            if (dumpPackage != null) {
13444                try {
13445                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13446                } catch (NameNotFoundException e) {
13447                    dumpUid = -1;
13448                }
13449            }
13450            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13451                int uid = mGrantedUriPermissions.keyAt(i);
13452                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13453                    continue;
13454                }
13455                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13456                if (!printed) {
13457                    if (needSep) pw.println();
13458                    needSep = true;
13459                    pw.println("  Granted Uri Permissions:");
13460                    printed = true;
13461                    printedAnything = true;
13462                }
13463                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13464                for (UriPermission perm : perms.values()) {
13465                    pw.print("    "); pw.println(perm);
13466                    if (dumpAll) {
13467                        perm.dump(pw, "      ");
13468                    }
13469                }
13470            }
13471        }
13472
13473        if (!printedAnything) {
13474            pw.println("  (nothing)");
13475        }
13476    }
13477
13478    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13479            int opti, boolean dumpAll, String dumpPackage) {
13480        boolean printed = false;
13481
13482        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13483
13484        if (mIntentSenderRecords.size() > 0) {
13485            Iterator<WeakReference<PendingIntentRecord>> it
13486                    = mIntentSenderRecords.values().iterator();
13487            while (it.hasNext()) {
13488                WeakReference<PendingIntentRecord> ref = it.next();
13489                PendingIntentRecord rec = ref != null ? ref.get(): null;
13490                if (dumpPackage != null && (rec == null
13491                        || !dumpPackage.equals(rec.key.packageName))) {
13492                    continue;
13493                }
13494                printed = true;
13495                if (rec != null) {
13496                    pw.print("  * "); pw.println(rec);
13497                    if (dumpAll) {
13498                        rec.dump(pw, "    ");
13499                    }
13500                } else {
13501                    pw.print("  * "); pw.println(ref);
13502                }
13503            }
13504        }
13505
13506        if (!printed) {
13507            pw.println("  (nothing)");
13508        }
13509    }
13510
13511    private static final int dumpProcessList(PrintWriter pw,
13512            ActivityManagerService service, List list,
13513            String prefix, String normalLabel, String persistentLabel,
13514            String dumpPackage) {
13515        int numPers = 0;
13516        final int N = list.size()-1;
13517        for (int i=N; i>=0; i--) {
13518            ProcessRecord r = (ProcessRecord)list.get(i);
13519            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13520                continue;
13521            }
13522            pw.println(String.format("%s%s #%2d: %s",
13523                    prefix, (r.persistent ? persistentLabel : normalLabel),
13524                    i, r.toString()));
13525            if (r.persistent) {
13526                numPers++;
13527            }
13528        }
13529        return numPers;
13530    }
13531
13532    private static final boolean dumpProcessOomList(PrintWriter pw,
13533            ActivityManagerService service, List<ProcessRecord> origList,
13534            String prefix, String normalLabel, String persistentLabel,
13535            boolean inclDetails, String dumpPackage) {
13536
13537        ArrayList<Pair<ProcessRecord, Integer>> list
13538                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13539        for (int i=0; i<origList.size(); i++) {
13540            ProcessRecord r = origList.get(i);
13541            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13542                continue;
13543            }
13544            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13545        }
13546
13547        if (list.size() <= 0) {
13548            return false;
13549        }
13550
13551        Comparator<Pair<ProcessRecord, Integer>> comparator
13552                = new Comparator<Pair<ProcessRecord, Integer>>() {
13553            @Override
13554            public int compare(Pair<ProcessRecord, Integer> object1,
13555                    Pair<ProcessRecord, Integer> object2) {
13556                if (object1.first.setAdj != object2.first.setAdj) {
13557                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13558                }
13559                if (object1.second.intValue() != object2.second.intValue()) {
13560                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13561                }
13562                return 0;
13563            }
13564        };
13565
13566        Collections.sort(list, comparator);
13567
13568        final long curRealtime = SystemClock.elapsedRealtime();
13569        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13570        final long curUptime = SystemClock.uptimeMillis();
13571        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13572
13573        for (int i=list.size()-1; i>=0; i--) {
13574            ProcessRecord r = list.get(i).first;
13575            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13576            char schedGroup;
13577            switch (r.setSchedGroup) {
13578                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13579                    schedGroup = 'B';
13580                    break;
13581                case Process.THREAD_GROUP_DEFAULT:
13582                    schedGroup = 'F';
13583                    break;
13584                default:
13585                    schedGroup = '?';
13586                    break;
13587            }
13588            char foreground;
13589            if (r.foregroundActivities) {
13590                foreground = 'A';
13591            } else if (r.foregroundServices) {
13592                foreground = 'S';
13593            } else {
13594                foreground = ' ';
13595            }
13596            String procState = ProcessList.makeProcStateString(r.curProcState);
13597            pw.print(prefix);
13598            pw.print(r.persistent ? persistentLabel : normalLabel);
13599            pw.print(" #");
13600            int num = (origList.size()-1)-list.get(i).second;
13601            if (num < 10) pw.print(' ');
13602            pw.print(num);
13603            pw.print(": ");
13604            pw.print(oomAdj);
13605            pw.print(' ');
13606            pw.print(schedGroup);
13607            pw.print('/');
13608            pw.print(foreground);
13609            pw.print('/');
13610            pw.print(procState);
13611            pw.print(" trm:");
13612            if (r.trimMemoryLevel < 10) pw.print(' ');
13613            pw.print(r.trimMemoryLevel);
13614            pw.print(' ');
13615            pw.print(r.toShortString());
13616            pw.print(" (");
13617            pw.print(r.adjType);
13618            pw.println(')');
13619            if (r.adjSource != null || r.adjTarget != null) {
13620                pw.print(prefix);
13621                pw.print("    ");
13622                if (r.adjTarget instanceof ComponentName) {
13623                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13624                } else if (r.adjTarget != null) {
13625                    pw.print(r.adjTarget.toString());
13626                } else {
13627                    pw.print("{null}");
13628                }
13629                pw.print("<=");
13630                if (r.adjSource instanceof ProcessRecord) {
13631                    pw.print("Proc{");
13632                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13633                    pw.println("}");
13634                } else if (r.adjSource != null) {
13635                    pw.println(r.adjSource.toString());
13636                } else {
13637                    pw.println("{null}");
13638                }
13639            }
13640            if (inclDetails) {
13641                pw.print(prefix);
13642                pw.print("    ");
13643                pw.print("oom: max="); pw.print(r.maxAdj);
13644                pw.print(" curRaw="); pw.print(r.curRawAdj);
13645                pw.print(" setRaw="); pw.print(r.setRawAdj);
13646                pw.print(" cur="); pw.print(r.curAdj);
13647                pw.print(" set="); pw.println(r.setAdj);
13648                pw.print(prefix);
13649                pw.print("    ");
13650                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13651                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13652                pw.print(" lastPss="); pw.print(r.lastPss);
13653                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13654                pw.print(prefix);
13655                pw.print("    ");
13656                pw.print("cached="); pw.print(r.cached);
13657                pw.print(" empty="); pw.print(r.empty);
13658                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13659
13660                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13661                    if (r.lastWakeTime != 0) {
13662                        long wtime;
13663                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13664                        synchronized (stats) {
13665                            wtime = stats.getProcessWakeTime(r.info.uid,
13666                                    r.pid, curRealtime);
13667                        }
13668                        long timeUsed = wtime - r.lastWakeTime;
13669                        pw.print(prefix);
13670                        pw.print("    ");
13671                        pw.print("keep awake over ");
13672                        TimeUtils.formatDuration(realtimeSince, pw);
13673                        pw.print(" used ");
13674                        TimeUtils.formatDuration(timeUsed, pw);
13675                        pw.print(" (");
13676                        pw.print((timeUsed*100)/realtimeSince);
13677                        pw.println("%)");
13678                    }
13679                    if (r.lastCpuTime != 0) {
13680                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13681                        pw.print(prefix);
13682                        pw.print("    ");
13683                        pw.print("run cpu over ");
13684                        TimeUtils.formatDuration(uptimeSince, pw);
13685                        pw.print(" used ");
13686                        TimeUtils.formatDuration(timeUsed, pw);
13687                        pw.print(" (");
13688                        pw.print((timeUsed*100)/uptimeSince);
13689                        pw.println("%)");
13690                    }
13691                }
13692            }
13693        }
13694        return true;
13695    }
13696
13697    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13698            String[] args) {
13699        ArrayList<ProcessRecord> procs;
13700        synchronized (this) {
13701            if (args != null && args.length > start
13702                    && args[start].charAt(0) != '-') {
13703                procs = new ArrayList<ProcessRecord>();
13704                int pid = -1;
13705                try {
13706                    pid = Integer.parseInt(args[start]);
13707                } catch (NumberFormatException e) {
13708                }
13709                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13710                    ProcessRecord proc = mLruProcesses.get(i);
13711                    if (proc.pid == pid) {
13712                        procs.add(proc);
13713                    } else if (allPkgs && proc.pkgList != null
13714                            && proc.pkgList.containsKey(args[start])) {
13715                        procs.add(proc);
13716                    } else if (proc.processName.equals(args[start])) {
13717                        procs.add(proc);
13718                    }
13719                }
13720                if (procs.size() <= 0) {
13721                    return null;
13722                }
13723            } else {
13724                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13725            }
13726        }
13727        return procs;
13728    }
13729
13730    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13731            PrintWriter pw, String[] args) {
13732        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13733        if (procs == null) {
13734            pw.println("No process found for: " + args[0]);
13735            return;
13736        }
13737
13738        long uptime = SystemClock.uptimeMillis();
13739        long realtime = SystemClock.elapsedRealtime();
13740        pw.println("Applications Graphics Acceleration Info:");
13741        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13742
13743        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13744            ProcessRecord r = procs.get(i);
13745            if (r.thread != null) {
13746                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13747                pw.flush();
13748                try {
13749                    TransferPipe tp = new TransferPipe();
13750                    try {
13751                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13752                        tp.go(fd);
13753                    } finally {
13754                        tp.kill();
13755                    }
13756                } catch (IOException e) {
13757                    pw.println("Failure while dumping the app: " + r);
13758                    pw.flush();
13759                } catch (RemoteException e) {
13760                    pw.println("Got a RemoteException while dumping the app " + r);
13761                    pw.flush();
13762                }
13763            }
13764        }
13765    }
13766
13767    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13768        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13769        if (procs == null) {
13770            pw.println("No process found for: " + args[0]);
13771            return;
13772        }
13773
13774        pw.println("Applications Database Info:");
13775
13776        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13777            ProcessRecord r = procs.get(i);
13778            if (r.thread != null) {
13779                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13780                pw.flush();
13781                try {
13782                    TransferPipe tp = new TransferPipe();
13783                    try {
13784                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13785                        tp.go(fd);
13786                    } finally {
13787                        tp.kill();
13788                    }
13789                } catch (IOException e) {
13790                    pw.println("Failure while dumping the app: " + r);
13791                    pw.flush();
13792                } catch (RemoteException e) {
13793                    pw.println("Got a RemoteException while dumping the app " + r);
13794                    pw.flush();
13795                }
13796            }
13797        }
13798    }
13799
13800    final static class MemItem {
13801        final boolean isProc;
13802        final String label;
13803        final String shortLabel;
13804        final long pss;
13805        final int id;
13806        final boolean hasActivities;
13807        ArrayList<MemItem> subitems;
13808
13809        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13810                boolean _hasActivities) {
13811            isProc = true;
13812            label = _label;
13813            shortLabel = _shortLabel;
13814            pss = _pss;
13815            id = _id;
13816            hasActivities = _hasActivities;
13817        }
13818
13819        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13820            isProc = false;
13821            label = _label;
13822            shortLabel = _shortLabel;
13823            pss = _pss;
13824            id = _id;
13825            hasActivities = false;
13826        }
13827    }
13828
13829    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13830            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13831        if (sort && !isCompact) {
13832            Collections.sort(items, new Comparator<MemItem>() {
13833                @Override
13834                public int compare(MemItem lhs, MemItem rhs) {
13835                    if (lhs.pss < rhs.pss) {
13836                        return 1;
13837                    } else if (lhs.pss > rhs.pss) {
13838                        return -1;
13839                    }
13840                    return 0;
13841                }
13842            });
13843        }
13844
13845        for (int i=0; i<items.size(); i++) {
13846            MemItem mi = items.get(i);
13847            if (!isCompact) {
13848                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13849            } else if (mi.isProc) {
13850                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13851                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13852                pw.println(mi.hasActivities ? ",a" : ",e");
13853            } else {
13854                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13855                pw.println(mi.pss);
13856            }
13857            if (mi.subitems != null) {
13858                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13859                        true, isCompact);
13860            }
13861        }
13862    }
13863
13864    // These are in KB.
13865    static final long[] DUMP_MEM_BUCKETS = new long[] {
13866        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13867        120*1024, 160*1024, 200*1024,
13868        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13869        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13870    };
13871
13872    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13873            boolean stackLike) {
13874        int start = label.lastIndexOf('.');
13875        if (start >= 0) start++;
13876        else start = 0;
13877        int end = label.length();
13878        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13879            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13880                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13881                out.append(bucket);
13882                out.append(stackLike ? "MB." : "MB ");
13883                out.append(label, start, end);
13884                return;
13885            }
13886        }
13887        out.append(memKB/1024);
13888        out.append(stackLike ? "MB." : "MB ");
13889        out.append(label, start, end);
13890    }
13891
13892    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13893            ProcessList.NATIVE_ADJ,
13894            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13895            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13896            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13897            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13898            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13899            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13900    };
13901    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13902            "Native",
13903            "System", "Persistent", "Persistent Service", "Foreground",
13904            "Visible", "Perceptible",
13905            "Heavy Weight", "Backup",
13906            "A Services", "Home",
13907            "Previous", "B Services", "Cached"
13908    };
13909    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13910            "native",
13911            "sys", "pers", "persvc", "fore",
13912            "vis", "percept",
13913            "heavy", "backup",
13914            "servicea", "home",
13915            "prev", "serviceb", "cached"
13916    };
13917
13918    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13919            long realtime, boolean isCheckinRequest, boolean isCompact) {
13920        if (isCheckinRequest || isCompact) {
13921            // short checkin version
13922            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13923        } else {
13924            pw.println("Applications Memory Usage (kB):");
13925            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13926        }
13927    }
13928
13929    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13930            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13931        boolean dumpDetails = false;
13932        boolean dumpFullDetails = false;
13933        boolean dumpDalvik = false;
13934        boolean oomOnly = false;
13935        boolean isCompact = false;
13936        boolean localOnly = false;
13937        boolean packages = false;
13938
13939        int opti = 0;
13940        while (opti < args.length) {
13941            String opt = args[opti];
13942            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13943                break;
13944            }
13945            opti++;
13946            if ("-a".equals(opt)) {
13947                dumpDetails = true;
13948                dumpFullDetails = true;
13949                dumpDalvik = true;
13950            } else if ("-d".equals(opt)) {
13951                dumpDalvik = true;
13952            } else if ("-c".equals(opt)) {
13953                isCompact = true;
13954            } else if ("--oom".equals(opt)) {
13955                oomOnly = true;
13956            } else if ("--local".equals(opt)) {
13957                localOnly = true;
13958            } else if ("--package".equals(opt)) {
13959                packages = true;
13960            } else if ("-h".equals(opt)) {
13961                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13962                pw.println("  -a: include all available information for each process.");
13963                pw.println("  -d: include dalvik details when dumping process details.");
13964                pw.println("  -c: dump in a compact machine-parseable representation.");
13965                pw.println("  --oom: only show processes organized by oom adj.");
13966                pw.println("  --local: only collect details locally, don't call process.");
13967                pw.println("  --package: interpret process arg as package, dumping all");
13968                pw.println("             processes that have loaded that package.");
13969                pw.println("If [process] is specified it can be the name or ");
13970                pw.println("pid of a specific process to dump.");
13971                return;
13972            } else {
13973                pw.println("Unknown argument: " + opt + "; use -h for help");
13974            }
13975        }
13976
13977        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13978        long uptime = SystemClock.uptimeMillis();
13979        long realtime = SystemClock.elapsedRealtime();
13980        final long[] tmpLong = new long[1];
13981
13982        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13983        if (procs == null) {
13984            // No Java processes.  Maybe they want to print a native process.
13985            if (args != null && args.length > opti
13986                    && args[opti].charAt(0) != '-') {
13987                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13988                        = new ArrayList<ProcessCpuTracker.Stats>();
13989                updateCpuStatsNow();
13990                int findPid = -1;
13991                try {
13992                    findPid = Integer.parseInt(args[opti]);
13993                } catch (NumberFormatException e) {
13994                }
13995                synchronized (mProcessCpuTracker) {
13996                    final int N = mProcessCpuTracker.countStats();
13997                    for (int i=0; i<N; i++) {
13998                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13999                        if (st.pid == findPid || (st.baseName != null
14000                                && st.baseName.equals(args[opti]))) {
14001                            nativeProcs.add(st);
14002                        }
14003                    }
14004                }
14005                if (nativeProcs.size() > 0) {
14006                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14007                            isCompact);
14008                    Debug.MemoryInfo mi = null;
14009                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14010                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14011                        final int pid = r.pid;
14012                        if (!isCheckinRequest && dumpDetails) {
14013                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14014                        }
14015                        if (mi == null) {
14016                            mi = new Debug.MemoryInfo();
14017                        }
14018                        if (dumpDetails || (!brief && !oomOnly)) {
14019                            Debug.getMemoryInfo(pid, mi);
14020                        } else {
14021                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14022                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14023                        }
14024                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14025                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14026                        if (isCheckinRequest) {
14027                            pw.println();
14028                        }
14029                    }
14030                    return;
14031                }
14032            }
14033            pw.println("No process found for: " + args[opti]);
14034            return;
14035        }
14036
14037        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14038            dumpDetails = true;
14039        }
14040
14041        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14042
14043        String[] innerArgs = new String[args.length-opti];
14044        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14045
14046        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14047        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14048        long nativePss=0, dalvikPss=0, otherPss=0;
14049        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14050
14051        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14052        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14053                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14054
14055        long totalPss = 0;
14056        long cachedPss = 0;
14057
14058        Debug.MemoryInfo mi = null;
14059        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14060            final ProcessRecord r = procs.get(i);
14061            final IApplicationThread thread;
14062            final int pid;
14063            final int oomAdj;
14064            final boolean hasActivities;
14065            synchronized (this) {
14066                thread = r.thread;
14067                pid = r.pid;
14068                oomAdj = r.getSetAdjWithServices();
14069                hasActivities = r.activities.size() > 0;
14070            }
14071            if (thread != null) {
14072                if (!isCheckinRequest && dumpDetails) {
14073                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14074                }
14075                if (mi == null) {
14076                    mi = new Debug.MemoryInfo();
14077                }
14078                if (dumpDetails || (!brief && !oomOnly)) {
14079                    Debug.getMemoryInfo(pid, mi);
14080                } else {
14081                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14082                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14083                }
14084                if (dumpDetails) {
14085                    if (localOnly) {
14086                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14087                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14088                        if (isCheckinRequest) {
14089                            pw.println();
14090                        }
14091                    } else {
14092                        try {
14093                            pw.flush();
14094                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14095                                    dumpDalvik, innerArgs);
14096                        } catch (RemoteException e) {
14097                            if (!isCheckinRequest) {
14098                                pw.println("Got RemoteException!");
14099                                pw.flush();
14100                            }
14101                        }
14102                    }
14103                }
14104
14105                final long myTotalPss = mi.getTotalPss();
14106                final long myTotalUss = mi.getTotalUss();
14107
14108                synchronized (this) {
14109                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14110                        // Record this for posterity if the process has been stable.
14111                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14112                    }
14113                }
14114
14115                if (!isCheckinRequest && mi != null) {
14116                    totalPss += myTotalPss;
14117                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14118                            (hasActivities ? " / activities)" : ")"),
14119                            r.processName, myTotalPss, pid, hasActivities);
14120                    procMems.add(pssItem);
14121                    procMemsMap.put(pid, pssItem);
14122
14123                    nativePss += mi.nativePss;
14124                    dalvikPss += mi.dalvikPss;
14125                    otherPss += mi.otherPss;
14126                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14127                        long mem = mi.getOtherPss(j);
14128                        miscPss[j] += mem;
14129                        otherPss -= mem;
14130                    }
14131
14132                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14133                        cachedPss += myTotalPss;
14134                    }
14135
14136                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14137                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14138                                || oomIndex == (oomPss.length-1)) {
14139                            oomPss[oomIndex] += myTotalPss;
14140                            if (oomProcs[oomIndex] == null) {
14141                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14142                            }
14143                            oomProcs[oomIndex].add(pssItem);
14144                            break;
14145                        }
14146                    }
14147                }
14148            }
14149        }
14150
14151        long nativeProcTotalPss = 0;
14152
14153        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14154            // If we are showing aggregations, also look for native processes to
14155            // include so that our aggregations are more accurate.
14156            updateCpuStatsNow();
14157            synchronized (mProcessCpuTracker) {
14158                final int N = mProcessCpuTracker.countStats();
14159                for (int i=0; i<N; i++) {
14160                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14161                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14162                        if (mi == null) {
14163                            mi = new Debug.MemoryInfo();
14164                        }
14165                        if (!brief && !oomOnly) {
14166                            Debug.getMemoryInfo(st.pid, mi);
14167                        } else {
14168                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14169                            mi.nativePrivateDirty = (int)tmpLong[0];
14170                        }
14171
14172                        final long myTotalPss = mi.getTotalPss();
14173                        totalPss += myTotalPss;
14174                        nativeProcTotalPss += myTotalPss;
14175
14176                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14177                                st.name, myTotalPss, st.pid, false);
14178                        procMems.add(pssItem);
14179
14180                        nativePss += mi.nativePss;
14181                        dalvikPss += mi.dalvikPss;
14182                        otherPss += mi.otherPss;
14183                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14184                            long mem = mi.getOtherPss(j);
14185                            miscPss[j] += mem;
14186                            otherPss -= mem;
14187                        }
14188                        oomPss[0] += myTotalPss;
14189                        if (oomProcs[0] == null) {
14190                            oomProcs[0] = new ArrayList<MemItem>();
14191                        }
14192                        oomProcs[0].add(pssItem);
14193                    }
14194                }
14195            }
14196
14197            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14198
14199            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14200            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14201            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14202            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14203                String label = Debug.MemoryInfo.getOtherLabel(j);
14204                catMems.add(new MemItem(label, label, miscPss[j], j));
14205            }
14206
14207            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14208            for (int j=0; j<oomPss.length; j++) {
14209                if (oomPss[j] != 0) {
14210                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14211                            : DUMP_MEM_OOM_LABEL[j];
14212                    MemItem item = new MemItem(label, label, oomPss[j],
14213                            DUMP_MEM_OOM_ADJ[j]);
14214                    item.subitems = oomProcs[j];
14215                    oomMems.add(item);
14216                }
14217            }
14218
14219            if (!brief && !oomOnly && !isCompact) {
14220                pw.println();
14221                pw.println("Total PSS by process:");
14222                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14223                pw.println();
14224            }
14225            if (!isCompact) {
14226                pw.println("Total PSS by OOM adjustment:");
14227            }
14228            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14229            if (!brief && !oomOnly) {
14230                PrintWriter out = categoryPw != null ? categoryPw : pw;
14231                if (!isCompact) {
14232                    out.println();
14233                    out.println("Total PSS by category:");
14234                }
14235                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14236            }
14237            if (!isCompact) {
14238                pw.println();
14239            }
14240            MemInfoReader memInfo = new MemInfoReader();
14241            memInfo.readMemInfo();
14242            if (nativeProcTotalPss > 0) {
14243                synchronized (this) {
14244                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14245                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14246                            memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14247                }
14248            }
14249            if (!brief) {
14250                if (!isCompact) {
14251                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14252                    pw.print(" kB (status ");
14253                    switch (mLastMemoryLevel) {
14254                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14255                            pw.println("normal)");
14256                            break;
14257                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14258                            pw.println("moderate)");
14259                            break;
14260                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14261                            pw.println("low)");
14262                            break;
14263                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14264                            pw.println("critical)");
14265                            break;
14266                        default:
14267                            pw.print(mLastMemoryLevel);
14268                            pw.println(")");
14269                            break;
14270                    }
14271                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14272                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14273                            pw.print(cachedPss); pw.print(" cached pss + ");
14274                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14275                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14276                } else {
14277                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14278                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14279                            + memInfo.getFreeSizeKb()); pw.print(",");
14280                    pw.println(totalPss - cachedPss);
14281                }
14282            }
14283            if (!isCompact) {
14284                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14285                        + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14286                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14287                        pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14288                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14289                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14290                        - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14291            }
14292            if (!brief) {
14293                if (memInfo.getZramTotalSizeKb() != 0) {
14294                    if (!isCompact) {
14295                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14296                                pw.print(" kB physical used for ");
14297                                pw.print(memInfo.getSwapTotalSizeKb()
14298                                        - memInfo.getSwapFreeSizeKb());
14299                                pw.print(" kB in swap (");
14300                                pw.print(memInfo.getSwapTotalSizeKb());
14301                                pw.println(" kB total swap)");
14302                    } else {
14303                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14304                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14305                                pw.println(memInfo.getSwapFreeSizeKb());
14306                    }
14307                }
14308                final int[] SINGLE_LONG_FORMAT = new int[] {
14309                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14310                };
14311                long[] longOut = new long[1];
14312                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14313                        SINGLE_LONG_FORMAT, null, longOut, null);
14314                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14315                longOut[0] = 0;
14316                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14317                        SINGLE_LONG_FORMAT, null, longOut, null);
14318                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14319                longOut[0] = 0;
14320                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14321                        SINGLE_LONG_FORMAT, null, longOut, null);
14322                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14323                longOut[0] = 0;
14324                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14325                        SINGLE_LONG_FORMAT, null, longOut, null);
14326                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14327                if (!isCompact) {
14328                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14329                        pw.print("      KSM: "); pw.print(sharing);
14330                                pw.print(" kB saved from shared ");
14331                                pw.print(shared); pw.println(" kB");
14332                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14333                                pw.print(voltile); pw.println(" kB volatile");
14334                    }
14335                    pw.print("   Tuning: ");
14336                    pw.print(ActivityManager.staticGetMemoryClass());
14337                    pw.print(" (large ");
14338                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14339                    pw.print("), oom ");
14340                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14341                    pw.print(" kB");
14342                    pw.print(", restore limit ");
14343                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14344                    pw.print(" kB");
14345                    if (ActivityManager.isLowRamDeviceStatic()) {
14346                        pw.print(" (low-ram)");
14347                    }
14348                    if (ActivityManager.isHighEndGfx()) {
14349                        pw.print(" (high-end-gfx)");
14350                    }
14351                    pw.println();
14352                } else {
14353                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14354                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14355                    pw.println(voltile);
14356                    pw.print("tuning,");
14357                    pw.print(ActivityManager.staticGetMemoryClass());
14358                    pw.print(',');
14359                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14360                    pw.print(',');
14361                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14362                    if (ActivityManager.isLowRamDeviceStatic()) {
14363                        pw.print(",low-ram");
14364                    }
14365                    if (ActivityManager.isHighEndGfx()) {
14366                        pw.print(",high-end-gfx");
14367                    }
14368                    pw.println();
14369                }
14370            }
14371        }
14372    }
14373
14374    /**
14375     * Searches array of arguments for the specified string
14376     * @param args array of argument strings
14377     * @param value value to search for
14378     * @return true if the value is contained in the array
14379     */
14380    private static boolean scanArgs(String[] args, String value) {
14381        if (args != null) {
14382            for (String arg : args) {
14383                if (value.equals(arg)) {
14384                    return true;
14385                }
14386            }
14387        }
14388        return false;
14389    }
14390
14391    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14392            ContentProviderRecord cpr, boolean always) {
14393        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14394
14395        if (!inLaunching || always) {
14396            synchronized (cpr) {
14397                cpr.launchingApp = null;
14398                cpr.notifyAll();
14399            }
14400            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14401            String names[] = cpr.info.authority.split(";");
14402            for (int j = 0; j < names.length; j++) {
14403                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14404            }
14405        }
14406
14407        for (int i=0; i<cpr.connections.size(); i++) {
14408            ContentProviderConnection conn = cpr.connections.get(i);
14409            if (conn.waiting) {
14410                // If this connection is waiting for the provider, then we don't
14411                // need to mess with its process unless we are always removing
14412                // or for some reason the provider is not currently launching.
14413                if (inLaunching && !always) {
14414                    continue;
14415                }
14416            }
14417            ProcessRecord capp = conn.client;
14418            conn.dead = true;
14419            if (conn.stableCount > 0) {
14420                if (!capp.persistent && capp.thread != null
14421                        && capp.pid != 0
14422                        && capp.pid != MY_PID) {
14423                    capp.kill("depends on provider "
14424                            + cpr.name.flattenToShortString()
14425                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14426                }
14427            } else if (capp.thread != null && conn.provider.provider != null) {
14428                try {
14429                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14430                } catch (RemoteException e) {
14431                }
14432                // In the protocol here, we don't expect the client to correctly
14433                // clean up this connection, we'll just remove it.
14434                cpr.connections.remove(i);
14435                conn.client.conProviders.remove(conn);
14436            }
14437        }
14438
14439        if (inLaunching && always) {
14440            mLaunchingProviders.remove(cpr);
14441        }
14442        return inLaunching;
14443    }
14444
14445    /**
14446     * Main code for cleaning up a process when it has gone away.  This is
14447     * called both as a result of the process dying, or directly when stopping
14448     * a process when running in single process mode.
14449     *
14450     * @return Returns true if the given process has been restarted, so the
14451     * app that was passed in must remain on the process lists.
14452     */
14453    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14454            boolean restarting, boolean allowRestart, int index) {
14455        if (index >= 0) {
14456            removeLruProcessLocked(app);
14457            ProcessList.remove(app.pid);
14458        }
14459
14460        mProcessesToGc.remove(app);
14461        mPendingPssProcesses.remove(app);
14462
14463        // Dismiss any open dialogs.
14464        if (app.crashDialog != null && !app.forceCrashReport) {
14465            app.crashDialog.dismiss();
14466            app.crashDialog = null;
14467        }
14468        if (app.anrDialog != null) {
14469            app.anrDialog.dismiss();
14470            app.anrDialog = null;
14471        }
14472        if (app.waitDialog != null) {
14473            app.waitDialog.dismiss();
14474            app.waitDialog = null;
14475        }
14476
14477        app.crashing = false;
14478        app.notResponding = false;
14479
14480        app.resetPackageList(mProcessStats);
14481        app.unlinkDeathRecipient();
14482        app.makeInactive(mProcessStats);
14483        app.waitingToKill = null;
14484        app.forcingToForeground = null;
14485        updateProcessForegroundLocked(app, false, false);
14486        app.foregroundActivities = false;
14487        app.hasShownUi = false;
14488        app.treatLikeActivity = false;
14489        app.hasAboveClient = false;
14490        app.hasClientActivities = false;
14491
14492        mServices.killServicesLocked(app, allowRestart);
14493
14494        boolean restart = false;
14495
14496        // Remove published content providers.
14497        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14498            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14499            final boolean always = app.bad || !allowRestart;
14500            if (removeDyingProviderLocked(app, cpr, always) || always) {
14501                // We left the provider in the launching list, need to
14502                // restart it.
14503                restart = true;
14504            }
14505
14506            cpr.provider = null;
14507            cpr.proc = null;
14508        }
14509        app.pubProviders.clear();
14510
14511        // Take care of any launching providers waiting for this process.
14512        if (checkAppInLaunchingProvidersLocked(app, false)) {
14513            restart = true;
14514        }
14515
14516        // Unregister from connected content providers.
14517        if (!app.conProviders.isEmpty()) {
14518            for (int i=0; i<app.conProviders.size(); i++) {
14519                ContentProviderConnection conn = app.conProviders.get(i);
14520                conn.provider.connections.remove(conn);
14521            }
14522            app.conProviders.clear();
14523        }
14524
14525        // At this point there may be remaining entries in mLaunchingProviders
14526        // where we were the only one waiting, so they are no longer of use.
14527        // Look for these and clean up if found.
14528        // XXX Commented out for now.  Trying to figure out a way to reproduce
14529        // the actual situation to identify what is actually going on.
14530        if (false) {
14531            for (int i=0; i<mLaunchingProviders.size(); i++) {
14532                ContentProviderRecord cpr = (ContentProviderRecord)
14533                        mLaunchingProviders.get(i);
14534                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14535                    synchronized (cpr) {
14536                        cpr.launchingApp = null;
14537                        cpr.notifyAll();
14538                    }
14539                }
14540            }
14541        }
14542
14543        skipCurrentReceiverLocked(app);
14544
14545        // Unregister any receivers.
14546        for (int i=app.receivers.size()-1; i>=0; i--) {
14547            removeReceiverLocked(app.receivers.valueAt(i));
14548        }
14549        app.receivers.clear();
14550
14551        // If the app is undergoing backup, tell the backup manager about it
14552        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14553            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14554                    + mBackupTarget.appInfo + " died during backup");
14555            try {
14556                IBackupManager bm = IBackupManager.Stub.asInterface(
14557                        ServiceManager.getService(Context.BACKUP_SERVICE));
14558                bm.agentDisconnected(app.info.packageName);
14559            } catch (RemoteException e) {
14560                // can't happen; backup manager is local
14561            }
14562        }
14563
14564        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14565            ProcessChangeItem item = mPendingProcessChanges.get(i);
14566            if (item.pid == app.pid) {
14567                mPendingProcessChanges.remove(i);
14568                mAvailProcessChanges.add(item);
14569            }
14570        }
14571        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14572
14573        // If the caller is restarting this app, then leave it in its
14574        // current lists and let the caller take care of it.
14575        if (restarting) {
14576            return false;
14577        }
14578
14579        if (!app.persistent || app.isolated) {
14580            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14581                    "Removing non-persistent process during cleanup: " + app);
14582            mProcessNames.remove(app.processName, app.uid);
14583            mIsolatedProcesses.remove(app.uid);
14584            if (mHeavyWeightProcess == app) {
14585                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14586                        mHeavyWeightProcess.userId, 0));
14587                mHeavyWeightProcess = null;
14588            }
14589        } else if (!app.removed) {
14590            // This app is persistent, so we need to keep its record around.
14591            // If it is not already on the pending app list, add it there
14592            // and start a new process for it.
14593            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14594                mPersistentStartingProcesses.add(app);
14595                restart = true;
14596            }
14597        }
14598        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14599                "Clean-up removing on hold: " + app);
14600        mProcessesOnHold.remove(app);
14601
14602        if (app == mHomeProcess) {
14603            mHomeProcess = null;
14604        }
14605        if (app == mPreviousProcess) {
14606            mPreviousProcess = null;
14607        }
14608
14609        if (restart && !app.isolated) {
14610            // We have components that still need to be running in the
14611            // process, so re-launch it.
14612            if (index < 0) {
14613                ProcessList.remove(app.pid);
14614            }
14615            mProcessNames.put(app.processName, app.uid, app);
14616            startProcessLocked(app, "restart", app.processName);
14617            return true;
14618        } else if (app.pid > 0 && app.pid != MY_PID) {
14619            // Goodbye!
14620            boolean removed;
14621            synchronized (mPidsSelfLocked) {
14622                mPidsSelfLocked.remove(app.pid);
14623                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14624            }
14625            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14626            if (app.isolated) {
14627                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14628            }
14629            app.setPid(0);
14630        }
14631        return false;
14632    }
14633
14634    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14635        // Look through the content providers we are waiting to have launched,
14636        // and if any run in this process then either schedule a restart of
14637        // the process or kill the client waiting for it if this process has
14638        // gone bad.
14639        int NL = mLaunchingProviders.size();
14640        boolean restart = false;
14641        for (int i=0; i<NL; i++) {
14642            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14643            if (cpr.launchingApp == app) {
14644                if (!alwaysBad && !app.bad) {
14645                    restart = true;
14646                } else {
14647                    removeDyingProviderLocked(app, cpr, true);
14648                    // cpr should have been removed from mLaunchingProviders
14649                    NL = mLaunchingProviders.size();
14650                    i--;
14651                }
14652            }
14653        }
14654        return restart;
14655    }
14656
14657    // =========================================================
14658    // SERVICES
14659    // =========================================================
14660
14661    @Override
14662    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14663            int flags) {
14664        enforceNotIsolatedCaller("getServices");
14665        synchronized (this) {
14666            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14667        }
14668    }
14669
14670    @Override
14671    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14672        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14673        synchronized (this) {
14674            return mServices.getRunningServiceControlPanelLocked(name);
14675        }
14676    }
14677
14678    @Override
14679    public ComponentName startService(IApplicationThread caller, Intent service,
14680            String resolvedType, int userId) {
14681        enforceNotIsolatedCaller("startService");
14682        // Refuse possible leaked file descriptors
14683        if (service != null && service.hasFileDescriptors() == true) {
14684            throw new IllegalArgumentException("File descriptors passed in Intent");
14685        }
14686
14687        if (DEBUG_SERVICE)
14688            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14689        synchronized(this) {
14690            final int callingPid = Binder.getCallingPid();
14691            final int callingUid = Binder.getCallingUid();
14692            final long origId = Binder.clearCallingIdentity();
14693            ComponentName res = mServices.startServiceLocked(caller, service,
14694                    resolvedType, callingPid, callingUid, userId);
14695            Binder.restoreCallingIdentity(origId);
14696            return res;
14697        }
14698    }
14699
14700    ComponentName startServiceInPackage(int uid,
14701            Intent service, String resolvedType, int userId) {
14702        synchronized(this) {
14703            if (DEBUG_SERVICE)
14704                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14705            final long origId = Binder.clearCallingIdentity();
14706            ComponentName res = mServices.startServiceLocked(null, service,
14707                    resolvedType, -1, uid, userId);
14708            Binder.restoreCallingIdentity(origId);
14709            return res;
14710        }
14711    }
14712
14713    @Override
14714    public int stopService(IApplicationThread caller, Intent service,
14715            String resolvedType, int userId) {
14716        enforceNotIsolatedCaller("stopService");
14717        // Refuse possible leaked file descriptors
14718        if (service != null && service.hasFileDescriptors() == true) {
14719            throw new IllegalArgumentException("File descriptors passed in Intent");
14720        }
14721
14722        synchronized(this) {
14723            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14724        }
14725    }
14726
14727    @Override
14728    public IBinder peekService(Intent service, String resolvedType) {
14729        enforceNotIsolatedCaller("peekService");
14730        // Refuse possible leaked file descriptors
14731        if (service != null && service.hasFileDescriptors() == true) {
14732            throw new IllegalArgumentException("File descriptors passed in Intent");
14733        }
14734        synchronized(this) {
14735            return mServices.peekServiceLocked(service, resolvedType);
14736        }
14737    }
14738
14739    @Override
14740    public boolean stopServiceToken(ComponentName className, IBinder token,
14741            int startId) {
14742        synchronized(this) {
14743            return mServices.stopServiceTokenLocked(className, token, startId);
14744        }
14745    }
14746
14747    @Override
14748    public void setServiceForeground(ComponentName className, IBinder token,
14749            int id, Notification notification, boolean removeNotification) {
14750        synchronized(this) {
14751            mServices.setServiceForegroundLocked(className, token, id, notification,
14752                    removeNotification);
14753        }
14754    }
14755
14756    @Override
14757    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14758            boolean requireFull, String name, String callerPackage) {
14759        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14760                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14761    }
14762
14763    int unsafeConvertIncomingUser(int userId) {
14764        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14765                ? mCurrentUserId : userId;
14766    }
14767
14768    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14769            int allowMode, String name, String callerPackage) {
14770        final int callingUserId = UserHandle.getUserId(callingUid);
14771        if (callingUserId == userId) {
14772            return userId;
14773        }
14774
14775        // Note that we may be accessing mCurrentUserId outside of a lock...
14776        // shouldn't be a big deal, if this is being called outside
14777        // of a locked context there is intrinsically a race with
14778        // the value the caller will receive and someone else changing it.
14779        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14780        // we will switch to the calling user if access to the current user fails.
14781        int targetUserId = unsafeConvertIncomingUser(userId);
14782
14783        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14784            final boolean allow;
14785            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14786                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14787                // If the caller has this permission, they always pass go.  And collect $200.
14788                allow = true;
14789            } else if (allowMode == ALLOW_FULL_ONLY) {
14790                // We require full access, sucks to be you.
14791                allow = false;
14792            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14793                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14794                // If the caller does not have either permission, they are always doomed.
14795                allow = false;
14796            } else if (allowMode == ALLOW_NON_FULL) {
14797                // We are blanket allowing non-full access, you lucky caller!
14798                allow = true;
14799            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14800                // We may or may not allow this depending on whether the two users are
14801                // in the same profile.
14802                synchronized (mUserProfileGroupIdsSelfLocked) {
14803                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14804                            UserInfo.NO_PROFILE_GROUP_ID);
14805                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14806                            UserInfo.NO_PROFILE_GROUP_ID);
14807                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14808                            && callingProfile == targetProfile;
14809                }
14810            } else {
14811                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14812            }
14813            if (!allow) {
14814                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14815                    // In this case, they would like to just execute as their
14816                    // owner user instead of failing.
14817                    targetUserId = callingUserId;
14818                } else {
14819                    StringBuilder builder = new StringBuilder(128);
14820                    builder.append("Permission Denial: ");
14821                    builder.append(name);
14822                    if (callerPackage != null) {
14823                        builder.append(" from ");
14824                        builder.append(callerPackage);
14825                    }
14826                    builder.append(" asks to run as user ");
14827                    builder.append(userId);
14828                    builder.append(" but is calling from user ");
14829                    builder.append(UserHandle.getUserId(callingUid));
14830                    builder.append("; this requires ");
14831                    builder.append(INTERACT_ACROSS_USERS_FULL);
14832                    if (allowMode != ALLOW_FULL_ONLY) {
14833                        builder.append(" or ");
14834                        builder.append(INTERACT_ACROSS_USERS);
14835                    }
14836                    String msg = builder.toString();
14837                    Slog.w(TAG, msg);
14838                    throw new SecurityException(msg);
14839                }
14840            }
14841        }
14842        if (!allowAll && targetUserId < 0) {
14843            throw new IllegalArgumentException(
14844                    "Call does not support special user #" + targetUserId);
14845        }
14846        // Check shell permission
14847        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14848            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14849                    targetUserId)) {
14850                throw new SecurityException("Shell does not have permission to access user "
14851                        + targetUserId + "\n " + Debug.getCallers(3));
14852            }
14853        }
14854        return targetUserId;
14855    }
14856
14857    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14858            String className, int flags) {
14859        boolean result = false;
14860        // For apps that don't have pre-defined UIDs, check for permission
14861        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14862            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14863                if (ActivityManager.checkUidPermission(
14864                        INTERACT_ACROSS_USERS,
14865                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14866                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14867                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14868                            + " requests FLAG_SINGLE_USER, but app does not hold "
14869                            + INTERACT_ACROSS_USERS;
14870                    Slog.w(TAG, msg);
14871                    throw new SecurityException(msg);
14872                }
14873                // Permission passed
14874                result = true;
14875            }
14876        } else if ("system".equals(componentProcessName)) {
14877            result = true;
14878        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14879            // Phone app and persistent apps are allowed to export singleuser providers.
14880            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14881                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14882        }
14883        if (DEBUG_MU) {
14884            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14885                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14886        }
14887        return result;
14888    }
14889
14890    /**
14891     * Checks to see if the caller is in the same app as the singleton
14892     * component, or the component is in a special app. It allows special apps
14893     * to export singleton components but prevents exporting singleton
14894     * components for regular apps.
14895     */
14896    boolean isValidSingletonCall(int callingUid, int componentUid) {
14897        int componentAppId = UserHandle.getAppId(componentUid);
14898        return UserHandle.isSameApp(callingUid, componentUid)
14899                || componentAppId == Process.SYSTEM_UID
14900                || componentAppId == Process.PHONE_UID
14901                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14902                        == PackageManager.PERMISSION_GRANTED;
14903    }
14904
14905    public int bindService(IApplicationThread caller, IBinder token,
14906            Intent service, String resolvedType,
14907            IServiceConnection connection, int flags, int userId) {
14908        enforceNotIsolatedCaller("bindService");
14909
14910        // Refuse possible leaked file descriptors
14911        if (service != null && service.hasFileDescriptors() == true) {
14912            throw new IllegalArgumentException("File descriptors passed in Intent");
14913        }
14914
14915        synchronized(this) {
14916            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14917                    connection, flags, userId);
14918        }
14919    }
14920
14921    public boolean unbindService(IServiceConnection connection) {
14922        synchronized (this) {
14923            return mServices.unbindServiceLocked(connection);
14924        }
14925    }
14926
14927    public void publishService(IBinder token, Intent intent, IBinder service) {
14928        // Refuse possible leaked file descriptors
14929        if (intent != null && intent.hasFileDescriptors() == true) {
14930            throw new IllegalArgumentException("File descriptors passed in Intent");
14931        }
14932
14933        synchronized(this) {
14934            if (!(token instanceof ServiceRecord)) {
14935                throw new IllegalArgumentException("Invalid service token");
14936            }
14937            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14938        }
14939    }
14940
14941    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14942        // Refuse possible leaked file descriptors
14943        if (intent != null && intent.hasFileDescriptors() == true) {
14944            throw new IllegalArgumentException("File descriptors passed in Intent");
14945        }
14946
14947        synchronized(this) {
14948            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14949        }
14950    }
14951
14952    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14953        synchronized(this) {
14954            if (!(token instanceof ServiceRecord)) {
14955                throw new IllegalArgumentException("Invalid service token");
14956            }
14957            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14958        }
14959    }
14960
14961    // =========================================================
14962    // BACKUP AND RESTORE
14963    // =========================================================
14964
14965    // Cause the target app to be launched if necessary and its backup agent
14966    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14967    // activity manager to announce its creation.
14968    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14969        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14970        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14971
14972        synchronized(this) {
14973            // !!! TODO: currently no check here that we're already bound
14974            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14975            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14976            synchronized (stats) {
14977                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14978            }
14979
14980            // Backup agent is now in use, its package can't be stopped.
14981            try {
14982                AppGlobals.getPackageManager().setPackageStoppedState(
14983                        app.packageName, false, UserHandle.getUserId(app.uid));
14984            } catch (RemoteException e) {
14985            } catch (IllegalArgumentException e) {
14986                Slog.w(TAG, "Failed trying to unstop package "
14987                        + app.packageName + ": " + e);
14988            }
14989
14990            BackupRecord r = new BackupRecord(ss, app, backupMode);
14991            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14992                    ? new ComponentName(app.packageName, app.backupAgentName)
14993                    : new ComponentName("android", "FullBackupAgent");
14994            // startProcessLocked() returns existing proc's record if it's already running
14995            ProcessRecord proc = startProcessLocked(app.processName, app,
14996                    false, 0, "backup", hostingName, false, false, false);
14997            if (proc == null) {
14998                Slog.e(TAG, "Unable to start backup agent process " + r);
14999                return false;
15000            }
15001
15002            r.app = proc;
15003            mBackupTarget = r;
15004            mBackupAppName = app.packageName;
15005
15006            // Try not to kill the process during backup
15007            updateOomAdjLocked(proc);
15008
15009            // If the process is already attached, schedule the creation of the backup agent now.
15010            // If it is not yet live, this will be done when it attaches to the framework.
15011            if (proc.thread != null) {
15012                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15013                try {
15014                    proc.thread.scheduleCreateBackupAgent(app,
15015                            compatibilityInfoForPackageLocked(app), backupMode);
15016                } catch (RemoteException e) {
15017                    // Will time out on the backup manager side
15018                }
15019            } else {
15020                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15021            }
15022            // Invariants: at this point, the target app process exists and the application
15023            // is either already running or in the process of coming up.  mBackupTarget and
15024            // mBackupAppName describe the app, so that when it binds back to the AM we
15025            // know that it's scheduled for a backup-agent operation.
15026        }
15027
15028        return true;
15029    }
15030
15031    @Override
15032    public void clearPendingBackup() {
15033        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15034        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15035
15036        synchronized (this) {
15037            mBackupTarget = null;
15038            mBackupAppName = null;
15039        }
15040    }
15041
15042    // A backup agent has just come up
15043    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15044        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15045                + " = " + agent);
15046
15047        synchronized(this) {
15048            if (!agentPackageName.equals(mBackupAppName)) {
15049                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15050                return;
15051            }
15052        }
15053
15054        long oldIdent = Binder.clearCallingIdentity();
15055        try {
15056            IBackupManager bm = IBackupManager.Stub.asInterface(
15057                    ServiceManager.getService(Context.BACKUP_SERVICE));
15058            bm.agentConnected(agentPackageName, agent);
15059        } catch (RemoteException e) {
15060            // can't happen; the backup manager service is local
15061        } catch (Exception e) {
15062            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15063            e.printStackTrace();
15064        } finally {
15065            Binder.restoreCallingIdentity(oldIdent);
15066        }
15067    }
15068
15069    // done with this agent
15070    public void unbindBackupAgent(ApplicationInfo appInfo) {
15071        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15072        if (appInfo == null) {
15073            Slog.w(TAG, "unbind backup agent for null app");
15074            return;
15075        }
15076
15077        synchronized(this) {
15078            try {
15079                if (mBackupAppName == null) {
15080                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15081                    return;
15082                }
15083
15084                if (!mBackupAppName.equals(appInfo.packageName)) {
15085                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15086                    return;
15087                }
15088
15089                // Not backing this app up any more; reset its OOM adjustment
15090                final ProcessRecord proc = mBackupTarget.app;
15091                updateOomAdjLocked(proc);
15092
15093                // If the app crashed during backup, 'thread' will be null here
15094                if (proc.thread != null) {
15095                    try {
15096                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15097                                compatibilityInfoForPackageLocked(appInfo));
15098                    } catch (Exception e) {
15099                        Slog.e(TAG, "Exception when unbinding backup agent:");
15100                        e.printStackTrace();
15101                    }
15102                }
15103            } finally {
15104                mBackupTarget = null;
15105                mBackupAppName = null;
15106            }
15107        }
15108    }
15109    // =========================================================
15110    // BROADCASTS
15111    // =========================================================
15112
15113    private final List getStickiesLocked(String action, IntentFilter filter,
15114            List cur, int userId) {
15115        final ContentResolver resolver = mContext.getContentResolver();
15116        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15117        if (stickies == null) {
15118            return cur;
15119        }
15120        final ArrayList<Intent> list = stickies.get(action);
15121        if (list == null) {
15122            return cur;
15123        }
15124        int N = list.size();
15125        for (int i=0; i<N; i++) {
15126            Intent intent = list.get(i);
15127            if (filter.match(resolver, intent, true, TAG) >= 0) {
15128                if (cur == null) {
15129                    cur = new ArrayList<Intent>();
15130                }
15131                cur.add(intent);
15132            }
15133        }
15134        return cur;
15135    }
15136
15137    boolean isPendingBroadcastProcessLocked(int pid) {
15138        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15139                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15140    }
15141
15142    void skipPendingBroadcastLocked(int pid) {
15143            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15144            for (BroadcastQueue queue : mBroadcastQueues) {
15145                queue.skipPendingBroadcastLocked(pid);
15146            }
15147    }
15148
15149    // The app just attached; send any pending broadcasts that it should receive
15150    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15151        boolean didSomething = false;
15152        for (BroadcastQueue queue : mBroadcastQueues) {
15153            didSomething |= queue.sendPendingBroadcastsLocked(app);
15154        }
15155        return didSomething;
15156    }
15157
15158    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15159            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15160        enforceNotIsolatedCaller("registerReceiver");
15161        int callingUid;
15162        int callingPid;
15163        synchronized(this) {
15164            ProcessRecord callerApp = null;
15165            if (caller != null) {
15166                callerApp = getRecordForAppLocked(caller);
15167                if (callerApp == null) {
15168                    throw new SecurityException(
15169                            "Unable to find app for caller " + caller
15170                            + " (pid=" + Binder.getCallingPid()
15171                            + ") when registering receiver " + receiver);
15172                }
15173                if (callerApp.info.uid != Process.SYSTEM_UID &&
15174                        !callerApp.pkgList.containsKey(callerPackage) &&
15175                        !"android".equals(callerPackage)) {
15176                    throw new SecurityException("Given caller package " + callerPackage
15177                            + " is not running in process " + callerApp);
15178                }
15179                callingUid = callerApp.info.uid;
15180                callingPid = callerApp.pid;
15181            } else {
15182                callerPackage = null;
15183                callingUid = Binder.getCallingUid();
15184                callingPid = Binder.getCallingPid();
15185            }
15186
15187            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15188                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15189
15190            List allSticky = null;
15191
15192            // Look for any matching sticky broadcasts...
15193            Iterator actions = filter.actionsIterator();
15194            if (actions != null) {
15195                while (actions.hasNext()) {
15196                    String action = (String)actions.next();
15197                    allSticky = getStickiesLocked(action, filter, allSticky,
15198                            UserHandle.USER_ALL);
15199                    allSticky = getStickiesLocked(action, filter, allSticky,
15200                            UserHandle.getUserId(callingUid));
15201                }
15202            } else {
15203                allSticky = getStickiesLocked(null, filter, allSticky,
15204                        UserHandle.USER_ALL);
15205                allSticky = getStickiesLocked(null, filter, allSticky,
15206                        UserHandle.getUserId(callingUid));
15207            }
15208
15209            // The first sticky in the list is returned directly back to
15210            // the client.
15211            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15212
15213            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15214                    + ": " + sticky);
15215
15216            if (receiver == null) {
15217                return sticky;
15218            }
15219
15220            ReceiverList rl
15221                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15222            if (rl == null) {
15223                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15224                        userId, receiver);
15225                if (rl.app != null) {
15226                    rl.app.receivers.add(rl);
15227                } else {
15228                    try {
15229                        receiver.asBinder().linkToDeath(rl, 0);
15230                    } catch (RemoteException e) {
15231                        return sticky;
15232                    }
15233                    rl.linkedToDeath = true;
15234                }
15235                mRegisteredReceivers.put(receiver.asBinder(), rl);
15236            } else if (rl.uid != callingUid) {
15237                throw new IllegalArgumentException(
15238                        "Receiver requested to register for uid " + callingUid
15239                        + " was previously registered for uid " + rl.uid);
15240            } else if (rl.pid != callingPid) {
15241                throw new IllegalArgumentException(
15242                        "Receiver requested to register for pid " + callingPid
15243                        + " was previously registered for pid " + rl.pid);
15244            } else if (rl.userId != userId) {
15245                throw new IllegalArgumentException(
15246                        "Receiver requested to register for user " + userId
15247                        + " was previously registered for user " + rl.userId);
15248            }
15249            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15250                    permission, callingUid, userId);
15251            rl.add(bf);
15252            if (!bf.debugCheck()) {
15253                Slog.w(TAG, "==> For Dynamic broadast");
15254            }
15255            mReceiverResolver.addFilter(bf);
15256
15257            // Enqueue broadcasts for all existing stickies that match
15258            // this filter.
15259            if (allSticky != null) {
15260                ArrayList receivers = new ArrayList();
15261                receivers.add(bf);
15262
15263                int N = allSticky.size();
15264                for (int i=0; i<N; i++) {
15265                    Intent intent = (Intent)allSticky.get(i);
15266                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15267                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15268                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15269                            null, null, false, true, true, -1);
15270                    queue.enqueueParallelBroadcastLocked(r);
15271                    queue.scheduleBroadcastsLocked();
15272                }
15273            }
15274
15275            return sticky;
15276        }
15277    }
15278
15279    public void unregisterReceiver(IIntentReceiver receiver) {
15280        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15281
15282        final long origId = Binder.clearCallingIdentity();
15283        try {
15284            boolean doTrim = false;
15285
15286            synchronized(this) {
15287                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15288                if (rl != null) {
15289                    if (rl.curBroadcast != null) {
15290                        BroadcastRecord r = rl.curBroadcast;
15291                        final boolean doNext = finishReceiverLocked(
15292                                receiver.asBinder(), r.resultCode, r.resultData,
15293                                r.resultExtras, r.resultAbort);
15294                        if (doNext) {
15295                            doTrim = true;
15296                            r.queue.processNextBroadcast(false);
15297                        }
15298                    }
15299
15300                    if (rl.app != null) {
15301                        rl.app.receivers.remove(rl);
15302                    }
15303                    removeReceiverLocked(rl);
15304                    if (rl.linkedToDeath) {
15305                        rl.linkedToDeath = false;
15306                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15307                    }
15308                }
15309            }
15310
15311            // If we actually concluded any broadcasts, we might now be able
15312            // to trim the recipients' apps from our working set
15313            if (doTrim) {
15314                trimApplications();
15315                return;
15316            }
15317
15318        } finally {
15319            Binder.restoreCallingIdentity(origId);
15320        }
15321    }
15322
15323    void removeReceiverLocked(ReceiverList rl) {
15324        mRegisteredReceivers.remove(rl.receiver.asBinder());
15325        int N = rl.size();
15326        for (int i=0; i<N; i++) {
15327            mReceiverResolver.removeFilter(rl.get(i));
15328        }
15329    }
15330
15331    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15332        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15333            ProcessRecord r = mLruProcesses.get(i);
15334            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15335                try {
15336                    r.thread.dispatchPackageBroadcast(cmd, packages);
15337                } catch (RemoteException ex) {
15338                }
15339            }
15340        }
15341    }
15342
15343    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15344            int callingUid, int[] users) {
15345        List<ResolveInfo> receivers = null;
15346        try {
15347            HashSet<ComponentName> singleUserReceivers = null;
15348            boolean scannedFirstReceivers = false;
15349            for (int user : users) {
15350                // Skip users that have Shell restrictions
15351                if (callingUid == Process.SHELL_UID
15352                        && getUserManagerLocked().hasUserRestriction(
15353                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15354                    continue;
15355                }
15356                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15357                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15358                if (user != 0 && newReceivers != null) {
15359                    // If this is not the primary user, we need to check for
15360                    // any receivers that should be filtered out.
15361                    for (int i=0; i<newReceivers.size(); i++) {
15362                        ResolveInfo ri = newReceivers.get(i);
15363                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15364                            newReceivers.remove(i);
15365                            i--;
15366                        }
15367                    }
15368                }
15369                if (newReceivers != null && newReceivers.size() == 0) {
15370                    newReceivers = null;
15371                }
15372                if (receivers == null) {
15373                    receivers = newReceivers;
15374                } else if (newReceivers != null) {
15375                    // We need to concatenate the additional receivers
15376                    // found with what we have do far.  This would be easy,
15377                    // but we also need to de-dup any receivers that are
15378                    // singleUser.
15379                    if (!scannedFirstReceivers) {
15380                        // Collect any single user receivers we had already retrieved.
15381                        scannedFirstReceivers = true;
15382                        for (int i=0; i<receivers.size(); i++) {
15383                            ResolveInfo ri = receivers.get(i);
15384                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15385                                ComponentName cn = new ComponentName(
15386                                        ri.activityInfo.packageName, ri.activityInfo.name);
15387                                if (singleUserReceivers == null) {
15388                                    singleUserReceivers = new HashSet<ComponentName>();
15389                                }
15390                                singleUserReceivers.add(cn);
15391                            }
15392                        }
15393                    }
15394                    // Add the new results to the existing results, tracking
15395                    // and de-dupping single user receivers.
15396                    for (int i=0; i<newReceivers.size(); i++) {
15397                        ResolveInfo ri = newReceivers.get(i);
15398                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15399                            ComponentName cn = new ComponentName(
15400                                    ri.activityInfo.packageName, ri.activityInfo.name);
15401                            if (singleUserReceivers == null) {
15402                                singleUserReceivers = new HashSet<ComponentName>();
15403                            }
15404                            if (!singleUserReceivers.contains(cn)) {
15405                                singleUserReceivers.add(cn);
15406                                receivers.add(ri);
15407                            }
15408                        } else {
15409                            receivers.add(ri);
15410                        }
15411                    }
15412                }
15413            }
15414        } catch (RemoteException ex) {
15415            // pm is in same process, this will never happen.
15416        }
15417        return receivers;
15418    }
15419
15420    private final int broadcastIntentLocked(ProcessRecord callerApp,
15421            String callerPackage, Intent intent, String resolvedType,
15422            IIntentReceiver resultTo, int resultCode, String resultData,
15423            Bundle map, String requiredPermission, int appOp,
15424            boolean ordered, boolean sticky, int callingPid, int callingUid,
15425            int userId) {
15426        intent = new Intent(intent);
15427
15428        // By default broadcasts do not go to stopped apps.
15429        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15430
15431        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15432            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15433            + " ordered=" + ordered + " userid=" + userId);
15434        if ((resultTo != null) && !ordered) {
15435            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15436        }
15437
15438        userId = handleIncomingUser(callingPid, callingUid, userId,
15439                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15440
15441        // Make sure that the user who is receiving this broadcast is started.
15442        // If not, we will just skip it.
15443
15444        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15445            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15446                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15447                Slog.w(TAG, "Skipping broadcast of " + intent
15448                        + ": user " + userId + " is stopped");
15449                return ActivityManager.BROADCAST_SUCCESS;
15450            }
15451        }
15452
15453        /*
15454         * Prevent non-system code (defined here to be non-persistent
15455         * processes) from sending protected broadcasts.
15456         */
15457        int callingAppId = UserHandle.getAppId(callingUid);
15458        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15459            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15460            || callingAppId == Process.NFC_UID || callingUid == 0) {
15461            // Always okay.
15462        } else if (callerApp == null || !callerApp.persistent) {
15463            try {
15464                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15465                        intent.getAction())) {
15466                    String msg = "Permission Denial: not allowed to send broadcast "
15467                            + intent.getAction() + " from pid="
15468                            + callingPid + ", uid=" + callingUid;
15469                    Slog.w(TAG, msg);
15470                    throw new SecurityException(msg);
15471                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15472                    // Special case for compatibility: we don't want apps to send this,
15473                    // but historically it has not been protected and apps may be using it
15474                    // to poke their own app widget.  So, instead of making it protected,
15475                    // just limit it to the caller.
15476                    if (callerApp == null) {
15477                        String msg = "Permission Denial: not allowed to send broadcast "
15478                                + intent.getAction() + " from unknown caller.";
15479                        Slog.w(TAG, msg);
15480                        throw new SecurityException(msg);
15481                    } else if (intent.getComponent() != null) {
15482                        // They are good enough to send to an explicit component...  verify
15483                        // it is being sent to the calling app.
15484                        if (!intent.getComponent().getPackageName().equals(
15485                                callerApp.info.packageName)) {
15486                            String msg = "Permission Denial: not allowed to send broadcast "
15487                                    + intent.getAction() + " to "
15488                                    + intent.getComponent().getPackageName() + " from "
15489                                    + callerApp.info.packageName;
15490                            Slog.w(TAG, msg);
15491                            throw new SecurityException(msg);
15492                        }
15493                    } else {
15494                        // Limit broadcast to their own package.
15495                        intent.setPackage(callerApp.info.packageName);
15496                    }
15497                }
15498            } catch (RemoteException e) {
15499                Slog.w(TAG, "Remote exception", e);
15500                return ActivityManager.BROADCAST_SUCCESS;
15501            }
15502        }
15503
15504        // Handle special intents: if this broadcast is from the package
15505        // manager about a package being removed, we need to remove all of
15506        // its activities from the history stack.
15507        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15508                intent.getAction());
15509        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15510                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15511                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15512                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15513                || uidRemoved) {
15514            if (checkComponentPermission(
15515                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15516                    callingPid, callingUid, -1, true)
15517                    == PackageManager.PERMISSION_GRANTED) {
15518                if (uidRemoved) {
15519                    final Bundle intentExtras = intent.getExtras();
15520                    final int uid = intentExtras != null
15521                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15522                    if (uid >= 0) {
15523                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15524                        synchronized (bs) {
15525                            bs.removeUidStatsLocked(uid);
15526                        }
15527                        mAppOpsService.uidRemoved(uid);
15528                    }
15529                } else {
15530                    // If resources are unavailable just force stop all
15531                    // those packages and flush the attribute cache as well.
15532                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15533                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15534                        if (list != null && (list.length > 0)) {
15535                            for (String pkg : list) {
15536                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15537                                        "storage unmount");
15538                            }
15539                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15540                            sendPackageBroadcastLocked(
15541                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15542                        }
15543                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15544                            intent.getAction())) {
15545                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15546                    } else {
15547                        Uri data = intent.getData();
15548                        String ssp;
15549                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15550                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15551                                    intent.getAction());
15552                            boolean fullUninstall = removed &&
15553                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15554                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15555                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15556                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15557                                        false, fullUninstall, userId,
15558                                        removed ? "pkg removed" : "pkg changed");
15559                            }
15560                            if (removed) {
15561                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15562                                        new String[] {ssp}, userId);
15563                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15564                                    mAppOpsService.packageRemoved(
15565                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15566
15567                                    // Remove all permissions granted from/to this package
15568                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15569                                }
15570                            }
15571                        }
15572                    }
15573                }
15574            } else {
15575                String msg = "Permission Denial: " + intent.getAction()
15576                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15577                        + ", uid=" + callingUid + ")"
15578                        + " requires "
15579                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15580                Slog.w(TAG, msg);
15581                throw new SecurityException(msg);
15582            }
15583
15584        // Special case for adding a package: by default turn on compatibility
15585        // mode.
15586        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15587            Uri data = intent.getData();
15588            String ssp;
15589            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15590                mCompatModePackages.handlePackageAddedLocked(ssp,
15591                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15592            }
15593        }
15594
15595        /*
15596         * If this is the time zone changed action, queue up a message that will reset the timezone
15597         * of all currently running processes. This message will get queued up before the broadcast
15598         * happens.
15599         */
15600        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15601            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15602        }
15603
15604        /*
15605         * If the user set the time, let all running processes know.
15606         */
15607        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15608            final int is24Hour = intent.getBooleanExtra(
15609                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15610            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15611            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15612            synchronized (stats) {
15613                stats.noteCurrentTimeChangedLocked();
15614            }
15615        }
15616
15617        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15618            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15619        }
15620
15621        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15622            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15623            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15624        }
15625
15626        // Add to the sticky list if requested.
15627        if (sticky) {
15628            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15629                    callingPid, callingUid)
15630                    != PackageManager.PERMISSION_GRANTED) {
15631                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15632                        + callingPid + ", uid=" + callingUid
15633                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15634                Slog.w(TAG, msg);
15635                throw new SecurityException(msg);
15636            }
15637            if (requiredPermission != null) {
15638                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15639                        + " and enforce permission " + requiredPermission);
15640                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15641            }
15642            if (intent.getComponent() != null) {
15643                throw new SecurityException(
15644                        "Sticky broadcasts can't target a specific component");
15645            }
15646            // We use userId directly here, since the "all" target is maintained
15647            // as a separate set of sticky broadcasts.
15648            if (userId != UserHandle.USER_ALL) {
15649                // But first, if this is not a broadcast to all users, then
15650                // make sure it doesn't conflict with an existing broadcast to
15651                // all users.
15652                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15653                        UserHandle.USER_ALL);
15654                if (stickies != null) {
15655                    ArrayList<Intent> list = stickies.get(intent.getAction());
15656                    if (list != null) {
15657                        int N = list.size();
15658                        int i;
15659                        for (i=0; i<N; i++) {
15660                            if (intent.filterEquals(list.get(i))) {
15661                                throw new IllegalArgumentException(
15662                                        "Sticky broadcast " + intent + " for user "
15663                                        + userId + " conflicts with existing global broadcast");
15664                            }
15665                        }
15666                    }
15667                }
15668            }
15669            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15670            if (stickies == null) {
15671                stickies = new ArrayMap<String, ArrayList<Intent>>();
15672                mStickyBroadcasts.put(userId, stickies);
15673            }
15674            ArrayList<Intent> list = stickies.get(intent.getAction());
15675            if (list == null) {
15676                list = new ArrayList<Intent>();
15677                stickies.put(intent.getAction(), list);
15678            }
15679            int N = list.size();
15680            int i;
15681            for (i=0; i<N; i++) {
15682                if (intent.filterEquals(list.get(i))) {
15683                    // This sticky already exists, replace it.
15684                    list.set(i, new Intent(intent));
15685                    break;
15686                }
15687            }
15688            if (i >= N) {
15689                list.add(new Intent(intent));
15690            }
15691        }
15692
15693        int[] users;
15694        if (userId == UserHandle.USER_ALL) {
15695            // Caller wants broadcast to go to all started users.
15696            users = mStartedUserArray;
15697        } else {
15698            // Caller wants broadcast to go to one specific user.
15699            users = new int[] {userId};
15700        }
15701
15702        // Figure out who all will receive this broadcast.
15703        List receivers = null;
15704        List<BroadcastFilter> registeredReceivers = null;
15705        // Need to resolve the intent to interested receivers...
15706        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15707                 == 0) {
15708            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15709        }
15710        if (intent.getComponent() == null) {
15711            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15712                // Query one target user at a time, excluding shell-restricted users
15713                UserManagerService ums = getUserManagerLocked();
15714                for (int i = 0; i < users.length; i++) {
15715                    if (ums.hasUserRestriction(
15716                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15717                        continue;
15718                    }
15719                    List<BroadcastFilter> registeredReceiversForUser =
15720                            mReceiverResolver.queryIntent(intent,
15721                                    resolvedType, false, users[i]);
15722                    if (registeredReceivers == null) {
15723                        registeredReceivers = registeredReceiversForUser;
15724                    } else if (registeredReceiversForUser != null) {
15725                        registeredReceivers.addAll(registeredReceiversForUser);
15726                    }
15727                }
15728            } else {
15729                registeredReceivers = mReceiverResolver.queryIntent(intent,
15730                        resolvedType, false, userId);
15731            }
15732        }
15733
15734        final boolean replacePending =
15735                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15736
15737        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15738                + " replacePending=" + replacePending);
15739
15740        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15741        if (!ordered && NR > 0) {
15742            // If we are not serializing this broadcast, then send the
15743            // registered receivers separately so they don't wait for the
15744            // components to be launched.
15745            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15746            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15747                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15748                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15749                    ordered, sticky, false, userId);
15750            if (DEBUG_BROADCAST) Slog.v(
15751                    TAG, "Enqueueing parallel broadcast " + r);
15752            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15753            if (!replaced) {
15754                queue.enqueueParallelBroadcastLocked(r);
15755                queue.scheduleBroadcastsLocked();
15756            }
15757            registeredReceivers = null;
15758            NR = 0;
15759        }
15760
15761        // Merge into one list.
15762        int ir = 0;
15763        if (receivers != null) {
15764            // A special case for PACKAGE_ADDED: do not allow the package
15765            // being added to see this broadcast.  This prevents them from
15766            // using this as a back door to get run as soon as they are
15767            // installed.  Maybe in the future we want to have a special install
15768            // broadcast or such for apps, but we'd like to deliberately make
15769            // this decision.
15770            String skipPackages[] = null;
15771            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15772                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15773                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15774                Uri data = intent.getData();
15775                if (data != null) {
15776                    String pkgName = data.getSchemeSpecificPart();
15777                    if (pkgName != null) {
15778                        skipPackages = new String[] { pkgName };
15779                    }
15780                }
15781            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15782                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15783            }
15784            if (skipPackages != null && (skipPackages.length > 0)) {
15785                for (String skipPackage : skipPackages) {
15786                    if (skipPackage != null) {
15787                        int NT = receivers.size();
15788                        for (int it=0; it<NT; it++) {
15789                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15790                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15791                                receivers.remove(it);
15792                                it--;
15793                                NT--;
15794                            }
15795                        }
15796                    }
15797                }
15798            }
15799
15800            int NT = receivers != null ? receivers.size() : 0;
15801            int it = 0;
15802            ResolveInfo curt = null;
15803            BroadcastFilter curr = null;
15804            while (it < NT && ir < NR) {
15805                if (curt == null) {
15806                    curt = (ResolveInfo)receivers.get(it);
15807                }
15808                if (curr == null) {
15809                    curr = registeredReceivers.get(ir);
15810                }
15811                if (curr.getPriority() >= curt.priority) {
15812                    // Insert this broadcast record into the final list.
15813                    receivers.add(it, curr);
15814                    ir++;
15815                    curr = null;
15816                    it++;
15817                    NT++;
15818                } else {
15819                    // Skip to the next ResolveInfo in the final list.
15820                    it++;
15821                    curt = null;
15822                }
15823            }
15824        }
15825        while (ir < NR) {
15826            if (receivers == null) {
15827                receivers = new ArrayList();
15828            }
15829            receivers.add(registeredReceivers.get(ir));
15830            ir++;
15831        }
15832
15833        if ((receivers != null && receivers.size() > 0)
15834                || resultTo != null) {
15835            BroadcastQueue queue = broadcastQueueForIntent(intent);
15836            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15837                    callerPackage, callingPid, callingUid, resolvedType,
15838                    requiredPermission, appOp, receivers, resultTo, resultCode,
15839                    resultData, map, ordered, sticky, false, userId);
15840            if (DEBUG_BROADCAST) Slog.v(
15841                    TAG, "Enqueueing ordered broadcast " + r
15842                    + ": prev had " + queue.mOrderedBroadcasts.size());
15843            if (DEBUG_BROADCAST) {
15844                int seq = r.intent.getIntExtra("seq", -1);
15845                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15846            }
15847            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15848            if (!replaced) {
15849                queue.enqueueOrderedBroadcastLocked(r);
15850                queue.scheduleBroadcastsLocked();
15851            }
15852        }
15853
15854        return ActivityManager.BROADCAST_SUCCESS;
15855    }
15856
15857    final Intent verifyBroadcastLocked(Intent intent) {
15858        // Refuse possible leaked file descriptors
15859        if (intent != null && intent.hasFileDescriptors() == true) {
15860            throw new IllegalArgumentException("File descriptors passed in Intent");
15861        }
15862
15863        int flags = intent.getFlags();
15864
15865        if (!mProcessesReady) {
15866            // if the caller really truly claims to know what they're doing, go
15867            // ahead and allow the broadcast without launching any receivers
15868            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15869                intent = new Intent(intent);
15870                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15871            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15872                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15873                        + " before boot completion");
15874                throw new IllegalStateException("Cannot broadcast before boot completed");
15875            }
15876        }
15877
15878        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15879            throw new IllegalArgumentException(
15880                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15881        }
15882
15883        return intent;
15884    }
15885
15886    public final int broadcastIntent(IApplicationThread caller,
15887            Intent intent, String resolvedType, IIntentReceiver resultTo,
15888            int resultCode, String resultData, Bundle map,
15889            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15890        enforceNotIsolatedCaller("broadcastIntent");
15891        synchronized(this) {
15892            intent = verifyBroadcastLocked(intent);
15893
15894            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15895            final int callingPid = Binder.getCallingPid();
15896            final int callingUid = Binder.getCallingUid();
15897            final long origId = Binder.clearCallingIdentity();
15898            int res = broadcastIntentLocked(callerApp,
15899                    callerApp != null ? callerApp.info.packageName : null,
15900                    intent, resolvedType, resultTo,
15901                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15902                    callingPid, callingUid, userId);
15903            Binder.restoreCallingIdentity(origId);
15904            return res;
15905        }
15906    }
15907
15908    int broadcastIntentInPackage(String packageName, int uid,
15909            Intent intent, String resolvedType, IIntentReceiver resultTo,
15910            int resultCode, String resultData, Bundle map,
15911            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15912        synchronized(this) {
15913            intent = verifyBroadcastLocked(intent);
15914
15915            final long origId = Binder.clearCallingIdentity();
15916            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15917                    resultTo, resultCode, resultData, map, requiredPermission,
15918                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15919            Binder.restoreCallingIdentity(origId);
15920            return res;
15921        }
15922    }
15923
15924    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15925        // Refuse possible leaked file descriptors
15926        if (intent != null && intent.hasFileDescriptors() == true) {
15927            throw new IllegalArgumentException("File descriptors passed in Intent");
15928        }
15929
15930        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15931                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15932
15933        synchronized(this) {
15934            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15935                    != PackageManager.PERMISSION_GRANTED) {
15936                String msg = "Permission Denial: unbroadcastIntent() from pid="
15937                        + Binder.getCallingPid()
15938                        + ", uid=" + Binder.getCallingUid()
15939                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15940                Slog.w(TAG, msg);
15941                throw new SecurityException(msg);
15942            }
15943            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15944            if (stickies != null) {
15945                ArrayList<Intent> list = stickies.get(intent.getAction());
15946                if (list != null) {
15947                    int N = list.size();
15948                    int i;
15949                    for (i=0; i<N; i++) {
15950                        if (intent.filterEquals(list.get(i))) {
15951                            list.remove(i);
15952                            break;
15953                        }
15954                    }
15955                    if (list.size() <= 0) {
15956                        stickies.remove(intent.getAction());
15957                    }
15958                }
15959                if (stickies.size() <= 0) {
15960                    mStickyBroadcasts.remove(userId);
15961                }
15962            }
15963        }
15964    }
15965
15966    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15967            String resultData, Bundle resultExtras, boolean resultAbort) {
15968        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15969        if (r == null) {
15970            Slog.w(TAG, "finishReceiver called but not found on queue");
15971            return false;
15972        }
15973
15974        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15975    }
15976
15977    void backgroundServicesFinishedLocked(int userId) {
15978        for (BroadcastQueue queue : mBroadcastQueues) {
15979            queue.backgroundServicesFinishedLocked(userId);
15980        }
15981    }
15982
15983    public void finishReceiver(IBinder who, int resultCode, String resultData,
15984            Bundle resultExtras, boolean resultAbort) {
15985        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15986
15987        // Refuse possible leaked file descriptors
15988        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15989            throw new IllegalArgumentException("File descriptors passed in Bundle");
15990        }
15991
15992        final long origId = Binder.clearCallingIdentity();
15993        try {
15994            boolean doNext = false;
15995            BroadcastRecord r;
15996
15997            synchronized(this) {
15998                r = broadcastRecordForReceiverLocked(who);
15999                if (r != null) {
16000                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16001                        resultData, resultExtras, resultAbort, true);
16002                }
16003            }
16004
16005            if (doNext) {
16006                r.queue.processNextBroadcast(false);
16007            }
16008            trimApplications();
16009        } finally {
16010            Binder.restoreCallingIdentity(origId);
16011        }
16012    }
16013
16014    // =========================================================
16015    // INSTRUMENTATION
16016    // =========================================================
16017
16018    public boolean startInstrumentation(ComponentName className,
16019            String profileFile, int flags, Bundle arguments,
16020            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16021            int userId, String abiOverride) {
16022        enforceNotIsolatedCaller("startInstrumentation");
16023        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16024                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16025        // Refuse possible leaked file descriptors
16026        if (arguments != null && arguments.hasFileDescriptors()) {
16027            throw new IllegalArgumentException("File descriptors passed in Bundle");
16028        }
16029
16030        synchronized(this) {
16031            InstrumentationInfo ii = null;
16032            ApplicationInfo ai = null;
16033            try {
16034                ii = mContext.getPackageManager().getInstrumentationInfo(
16035                    className, STOCK_PM_FLAGS);
16036                ai = AppGlobals.getPackageManager().getApplicationInfo(
16037                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16038            } catch (PackageManager.NameNotFoundException e) {
16039            } catch (RemoteException e) {
16040            }
16041            if (ii == null) {
16042                reportStartInstrumentationFailure(watcher, className,
16043                        "Unable to find instrumentation info for: " + className);
16044                return false;
16045            }
16046            if (ai == null) {
16047                reportStartInstrumentationFailure(watcher, className,
16048                        "Unable to find instrumentation target package: " + ii.targetPackage);
16049                return false;
16050            }
16051
16052            int match = mContext.getPackageManager().checkSignatures(
16053                    ii.targetPackage, ii.packageName);
16054            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16055                String msg = "Permission Denial: starting instrumentation "
16056                        + className + " from pid="
16057                        + Binder.getCallingPid()
16058                        + ", uid=" + Binder.getCallingPid()
16059                        + " not allowed because package " + ii.packageName
16060                        + " does not have a signature matching the target "
16061                        + ii.targetPackage;
16062                reportStartInstrumentationFailure(watcher, className, msg);
16063                throw new SecurityException(msg);
16064            }
16065
16066            final long origId = Binder.clearCallingIdentity();
16067            // Instrumentation can kill and relaunch even persistent processes
16068            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16069                    "start instr");
16070            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16071            app.instrumentationClass = className;
16072            app.instrumentationInfo = ai;
16073            app.instrumentationProfileFile = profileFile;
16074            app.instrumentationArguments = arguments;
16075            app.instrumentationWatcher = watcher;
16076            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16077            app.instrumentationResultClass = className;
16078            Binder.restoreCallingIdentity(origId);
16079        }
16080
16081        return true;
16082    }
16083
16084    /**
16085     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16086     * error to the logs, but if somebody is watching, send the report there too.  This enables
16087     * the "am" command to report errors with more information.
16088     *
16089     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16090     * @param cn The component name of the instrumentation.
16091     * @param report The error report.
16092     */
16093    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16094            ComponentName cn, String report) {
16095        Slog.w(TAG, report);
16096        try {
16097            if (watcher != null) {
16098                Bundle results = new Bundle();
16099                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16100                results.putString("Error", report);
16101                watcher.instrumentationStatus(cn, -1, results);
16102            }
16103        } catch (RemoteException e) {
16104            Slog.w(TAG, e);
16105        }
16106    }
16107
16108    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16109        if (app.instrumentationWatcher != null) {
16110            try {
16111                // NOTE:  IInstrumentationWatcher *must* be oneway here
16112                app.instrumentationWatcher.instrumentationFinished(
16113                    app.instrumentationClass,
16114                    resultCode,
16115                    results);
16116            } catch (RemoteException e) {
16117            }
16118        }
16119        if (app.instrumentationUiAutomationConnection != null) {
16120            try {
16121                app.instrumentationUiAutomationConnection.shutdown();
16122            } catch (RemoteException re) {
16123                /* ignore */
16124            }
16125            // Only a UiAutomation can set this flag and now that
16126            // it is finished we make sure it is reset to its default.
16127            mUserIsMonkey = false;
16128        }
16129        app.instrumentationWatcher = null;
16130        app.instrumentationUiAutomationConnection = null;
16131        app.instrumentationClass = null;
16132        app.instrumentationInfo = null;
16133        app.instrumentationProfileFile = null;
16134        app.instrumentationArguments = null;
16135
16136        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16137                "finished inst");
16138    }
16139
16140    public void finishInstrumentation(IApplicationThread target,
16141            int resultCode, Bundle results) {
16142        int userId = UserHandle.getCallingUserId();
16143        // Refuse possible leaked file descriptors
16144        if (results != null && results.hasFileDescriptors()) {
16145            throw new IllegalArgumentException("File descriptors passed in Intent");
16146        }
16147
16148        synchronized(this) {
16149            ProcessRecord app = getRecordForAppLocked(target);
16150            if (app == null) {
16151                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16152                return;
16153            }
16154            final long origId = Binder.clearCallingIdentity();
16155            finishInstrumentationLocked(app, resultCode, results);
16156            Binder.restoreCallingIdentity(origId);
16157        }
16158    }
16159
16160    // =========================================================
16161    // CONFIGURATION
16162    // =========================================================
16163
16164    public ConfigurationInfo getDeviceConfigurationInfo() {
16165        ConfigurationInfo config = new ConfigurationInfo();
16166        synchronized (this) {
16167            config.reqTouchScreen = mConfiguration.touchscreen;
16168            config.reqKeyboardType = mConfiguration.keyboard;
16169            config.reqNavigation = mConfiguration.navigation;
16170            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16171                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16172                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16173            }
16174            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16175                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16176                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16177            }
16178            config.reqGlEsVersion = GL_ES_VERSION;
16179        }
16180        return config;
16181    }
16182
16183    ActivityStack getFocusedStack() {
16184        return mStackSupervisor.getFocusedStack();
16185    }
16186
16187    public Configuration getConfiguration() {
16188        Configuration ci;
16189        synchronized(this) {
16190            ci = new Configuration(mConfiguration);
16191        }
16192        return ci;
16193    }
16194
16195    public void updatePersistentConfiguration(Configuration values) {
16196        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16197                "updateConfiguration()");
16198        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16199                "updateConfiguration()");
16200        if (values == null) {
16201            throw new NullPointerException("Configuration must not be null");
16202        }
16203
16204        synchronized(this) {
16205            final long origId = Binder.clearCallingIdentity();
16206            updateConfigurationLocked(values, null, true, false);
16207            Binder.restoreCallingIdentity(origId);
16208        }
16209    }
16210
16211    public void updateConfiguration(Configuration values) {
16212        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16213                "updateConfiguration()");
16214
16215        synchronized(this) {
16216            if (values == null && mWindowManager != null) {
16217                // sentinel: fetch the current configuration from the window manager
16218                values = mWindowManager.computeNewConfiguration();
16219            }
16220
16221            if (mWindowManager != null) {
16222                mProcessList.applyDisplaySize(mWindowManager);
16223            }
16224
16225            final long origId = Binder.clearCallingIdentity();
16226            if (values != null) {
16227                Settings.System.clearConfiguration(values);
16228            }
16229            updateConfigurationLocked(values, null, false, false);
16230            Binder.restoreCallingIdentity(origId);
16231        }
16232    }
16233
16234    /**
16235     * Do either or both things: (1) change the current configuration, and (2)
16236     * make sure the given activity is running with the (now) current
16237     * configuration.  Returns true if the activity has been left running, or
16238     * false if <var>starting</var> is being destroyed to match the new
16239     * configuration.
16240     * @param persistent TODO
16241     */
16242    boolean updateConfigurationLocked(Configuration values,
16243            ActivityRecord starting, boolean persistent, boolean initLocale) {
16244        int changes = 0;
16245
16246        if (values != null) {
16247            Configuration newConfig = new Configuration(mConfiguration);
16248            changes = newConfig.updateFrom(values);
16249            if (changes != 0) {
16250                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16251                    Slog.i(TAG, "Updating configuration to: " + values);
16252                }
16253
16254                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16255
16256                if (values.locale != null && !initLocale) {
16257                    saveLocaleLocked(values.locale,
16258                                     !values.locale.equals(mConfiguration.locale),
16259                                     values.userSetLocale);
16260                }
16261
16262                mConfigurationSeq++;
16263                if (mConfigurationSeq <= 0) {
16264                    mConfigurationSeq = 1;
16265                }
16266                newConfig.seq = mConfigurationSeq;
16267                mConfiguration = newConfig;
16268                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16269                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16270                //mUsageStatsService.noteStartConfig(newConfig);
16271
16272                final Configuration configCopy = new Configuration(mConfiguration);
16273
16274                // TODO: If our config changes, should we auto dismiss any currently
16275                // showing dialogs?
16276                mShowDialogs = shouldShowDialogs(newConfig);
16277
16278                AttributeCache ac = AttributeCache.instance();
16279                if (ac != null) {
16280                    ac.updateConfiguration(configCopy);
16281                }
16282
16283                // Make sure all resources in our process are updated
16284                // right now, so that anyone who is going to retrieve
16285                // resource values after we return will be sure to get
16286                // the new ones.  This is especially important during
16287                // boot, where the first config change needs to guarantee
16288                // all resources have that config before following boot
16289                // code is executed.
16290                mSystemThread.applyConfigurationToResources(configCopy);
16291
16292                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16293                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16294                    msg.obj = new Configuration(configCopy);
16295                    mHandler.sendMessage(msg);
16296                }
16297
16298                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16299                    ProcessRecord app = mLruProcesses.get(i);
16300                    try {
16301                        if (app.thread != null) {
16302                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16303                                    + app.processName + " new config " + mConfiguration);
16304                            app.thread.scheduleConfigurationChanged(configCopy);
16305                        }
16306                    } catch (Exception e) {
16307                    }
16308                }
16309                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16310                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16311                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16312                        | Intent.FLAG_RECEIVER_FOREGROUND);
16313                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16314                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16315                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16316                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16317                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16318                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16319                    broadcastIntentLocked(null, null, intent,
16320                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16321                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16322                }
16323            }
16324        }
16325
16326        boolean kept = true;
16327        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16328        // mainStack is null during startup.
16329        if (mainStack != null) {
16330            if (changes != 0 && starting == null) {
16331                // If the configuration changed, and the caller is not already
16332                // in the process of starting an activity, then find the top
16333                // activity to check if its configuration needs to change.
16334                starting = mainStack.topRunningActivityLocked(null);
16335            }
16336
16337            if (starting != null) {
16338                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16339                // And we need to make sure at this point that all other activities
16340                // are made visible with the correct configuration.
16341                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16342            }
16343        }
16344
16345        if (values != null && mWindowManager != null) {
16346            mWindowManager.setNewConfiguration(mConfiguration);
16347        }
16348
16349        return kept;
16350    }
16351
16352    /**
16353     * Decide based on the configuration whether we should shouw the ANR,
16354     * crash, etc dialogs.  The idea is that if there is no affordnace to
16355     * press the on-screen buttons, we shouldn't show the dialog.
16356     *
16357     * A thought: SystemUI might also want to get told about this, the Power
16358     * dialog / global actions also might want different behaviors.
16359     */
16360    private static final boolean shouldShowDialogs(Configuration config) {
16361        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16362                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16363    }
16364
16365    /**
16366     * Save the locale.  You must be inside a synchronized (this) block.
16367     */
16368    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16369        if(isDiff) {
16370            SystemProperties.set("user.language", l.getLanguage());
16371            SystemProperties.set("user.region", l.getCountry());
16372        }
16373
16374        if(isPersist) {
16375            SystemProperties.set("persist.sys.language", l.getLanguage());
16376            SystemProperties.set("persist.sys.country", l.getCountry());
16377            SystemProperties.set("persist.sys.localevar", l.getVariant());
16378
16379            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16380        }
16381    }
16382
16383    @Override
16384    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16385        synchronized (this) {
16386            ActivityRecord srec = ActivityRecord.forToken(token);
16387            if (srec.task != null && srec.task.stack != null) {
16388                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16389            }
16390        }
16391        return false;
16392    }
16393
16394    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16395            Intent resultData) {
16396
16397        synchronized (this) {
16398            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16399            if (stack != null) {
16400                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16401            }
16402            return false;
16403        }
16404    }
16405
16406    public int getLaunchedFromUid(IBinder activityToken) {
16407        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16408        if (srec == null) {
16409            return -1;
16410        }
16411        return srec.launchedFromUid;
16412    }
16413
16414    public String getLaunchedFromPackage(IBinder activityToken) {
16415        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16416        if (srec == null) {
16417            return null;
16418        }
16419        return srec.launchedFromPackage;
16420    }
16421
16422    // =========================================================
16423    // LIFETIME MANAGEMENT
16424    // =========================================================
16425
16426    // Returns which broadcast queue the app is the current [or imminent] receiver
16427    // on, or 'null' if the app is not an active broadcast recipient.
16428    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16429        BroadcastRecord r = app.curReceiver;
16430        if (r != null) {
16431            return r.queue;
16432        }
16433
16434        // It's not the current receiver, but it might be starting up to become one
16435        synchronized (this) {
16436            for (BroadcastQueue queue : mBroadcastQueues) {
16437                r = queue.mPendingBroadcast;
16438                if (r != null && r.curApp == app) {
16439                    // found it; report which queue it's in
16440                    return queue;
16441                }
16442            }
16443        }
16444
16445        return null;
16446    }
16447
16448    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16449            boolean doingAll, long now) {
16450        if (mAdjSeq == app.adjSeq) {
16451            // This adjustment has already been computed.
16452            return app.curRawAdj;
16453        }
16454
16455        if (app.thread == null) {
16456            app.adjSeq = mAdjSeq;
16457            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16458            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16459            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16460        }
16461
16462        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16463        app.adjSource = null;
16464        app.adjTarget = null;
16465        app.empty = false;
16466        app.cached = false;
16467
16468        final int activitiesSize = app.activities.size();
16469
16470        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16471            // The max adjustment doesn't allow this app to be anything
16472            // below foreground, so it is not worth doing work for it.
16473            app.adjType = "fixed";
16474            app.adjSeq = mAdjSeq;
16475            app.curRawAdj = app.maxAdj;
16476            app.foregroundActivities = false;
16477            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16478            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16479            // System processes can do UI, and when they do we want to have
16480            // them trim their memory after the user leaves the UI.  To
16481            // facilitate this, here we need to determine whether or not it
16482            // is currently showing UI.
16483            app.systemNoUi = true;
16484            if (app == TOP_APP) {
16485                app.systemNoUi = false;
16486            } else if (activitiesSize > 0) {
16487                for (int j = 0; j < activitiesSize; j++) {
16488                    final ActivityRecord r = app.activities.get(j);
16489                    if (r.visible) {
16490                        app.systemNoUi = false;
16491                    }
16492                }
16493            }
16494            if (!app.systemNoUi) {
16495                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16496            }
16497            return (app.curAdj=app.maxAdj);
16498        }
16499
16500        app.systemNoUi = false;
16501
16502        // Determine the importance of the process, starting with most
16503        // important to least, and assign an appropriate OOM adjustment.
16504        int adj;
16505        int schedGroup;
16506        int procState;
16507        boolean foregroundActivities = false;
16508        BroadcastQueue queue;
16509        if (app == TOP_APP) {
16510            // The last app on the list is the foreground app.
16511            adj = ProcessList.FOREGROUND_APP_ADJ;
16512            schedGroup = Process.THREAD_GROUP_DEFAULT;
16513            app.adjType = "top-activity";
16514            foregroundActivities = true;
16515            procState = ActivityManager.PROCESS_STATE_TOP;
16516        } else if (app.instrumentationClass != null) {
16517            // Don't want to kill running instrumentation.
16518            adj = ProcessList.FOREGROUND_APP_ADJ;
16519            schedGroup = Process.THREAD_GROUP_DEFAULT;
16520            app.adjType = "instrumentation";
16521            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16522        } else if ((queue = isReceivingBroadcast(app)) != null) {
16523            // An app that is currently receiving a broadcast also
16524            // counts as being in the foreground for OOM killer purposes.
16525            // It's placed in a sched group based on the nature of the
16526            // broadcast as reflected by which queue it's active in.
16527            adj = ProcessList.FOREGROUND_APP_ADJ;
16528            schedGroup = (queue == mFgBroadcastQueue)
16529                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16530            app.adjType = "broadcast";
16531            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16532        } else if (app.executingServices.size() > 0) {
16533            // An app that is currently executing a service callback also
16534            // counts as being in the foreground.
16535            adj = ProcessList.FOREGROUND_APP_ADJ;
16536            schedGroup = app.execServicesFg ?
16537                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16538            app.adjType = "exec-service";
16539            procState = ActivityManager.PROCESS_STATE_SERVICE;
16540            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16541        } else {
16542            // As far as we know the process is empty.  We may change our mind later.
16543            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16544            // At this point we don't actually know the adjustment.  Use the cached adj
16545            // value that the caller wants us to.
16546            adj = cachedAdj;
16547            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16548            app.cached = true;
16549            app.empty = true;
16550            app.adjType = "cch-empty";
16551        }
16552
16553        // Examine all activities if not already foreground.
16554        if (!foregroundActivities && activitiesSize > 0) {
16555            for (int j = 0; j < activitiesSize; j++) {
16556                final ActivityRecord r = app.activities.get(j);
16557                if (r.app != app) {
16558                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16559                            + app + "?!?");
16560                    continue;
16561                }
16562                if (r.visible) {
16563                    // App has a visible activity; only upgrade adjustment.
16564                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16565                        adj = ProcessList.VISIBLE_APP_ADJ;
16566                        app.adjType = "visible";
16567                    }
16568                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16569                        procState = ActivityManager.PROCESS_STATE_TOP;
16570                    }
16571                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16572                    app.cached = false;
16573                    app.empty = false;
16574                    foregroundActivities = true;
16575                    break;
16576                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16577                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16578                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16579                        app.adjType = "pausing";
16580                    }
16581                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16582                        procState = ActivityManager.PROCESS_STATE_TOP;
16583                    }
16584                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16585                    app.cached = false;
16586                    app.empty = false;
16587                    foregroundActivities = true;
16588                } else if (r.state == ActivityState.STOPPING) {
16589                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16590                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16591                        app.adjType = "stopping";
16592                    }
16593                    // For the process state, we will at this point consider the
16594                    // process to be cached.  It will be cached either as an activity
16595                    // or empty depending on whether the activity is finishing.  We do
16596                    // this so that we can treat the process as cached for purposes of
16597                    // memory trimming (determing current memory level, trim command to
16598                    // send to process) since there can be an arbitrary number of stopping
16599                    // processes and they should soon all go into the cached state.
16600                    if (!r.finishing) {
16601                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16602                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16603                        }
16604                    }
16605                    app.cached = false;
16606                    app.empty = false;
16607                    foregroundActivities = true;
16608                } else {
16609                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16610                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16611                        app.adjType = "cch-act";
16612                    }
16613                }
16614            }
16615        }
16616
16617        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16618            if (app.foregroundServices) {
16619                // The user is aware of this app, so make it visible.
16620                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16621                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16622                app.cached = false;
16623                app.adjType = "fg-service";
16624                schedGroup = Process.THREAD_GROUP_DEFAULT;
16625            } else if (app.forcingToForeground != null) {
16626                // The user is aware of this app, so make it visible.
16627                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16628                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16629                app.cached = false;
16630                app.adjType = "force-fg";
16631                app.adjSource = app.forcingToForeground;
16632                schedGroup = Process.THREAD_GROUP_DEFAULT;
16633            }
16634        }
16635
16636        if (app == mHeavyWeightProcess) {
16637            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16638                // We don't want to kill the current heavy-weight process.
16639                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16640                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16641                app.cached = false;
16642                app.adjType = "heavy";
16643            }
16644            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16645                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16646            }
16647        }
16648
16649        if (app == mHomeProcess) {
16650            if (adj > ProcessList.HOME_APP_ADJ) {
16651                // This process is hosting what we currently consider to be the
16652                // home app, so we don't want to let it go into the background.
16653                adj = ProcessList.HOME_APP_ADJ;
16654                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16655                app.cached = false;
16656                app.adjType = "home";
16657            }
16658            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16659                procState = ActivityManager.PROCESS_STATE_HOME;
16660            }
16661        }
16662
16663        if (app == mPreviousProcess && app.activities.size() > 0) {
16664            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16665                // This was the previous process that showed UI to the user.
16666                // We want to try to keep it around more aggressively, to give
16667                // a good experience around switching between two apps.
16668                adj = ProcessList.PREVIOUS_APP_ADJ;
16669                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16670                app.cached = false;
16671                app.adjType = "previous";
16672            }
16673            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16674                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16675            }
16676        }
16677
16678        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16679                + " reason=" + app.adjType);
16680
16681        // By default, we use the computed adjustment.  It may be changed if
16682        // there are applications dependent on our services or providers, but
16683        // this gives us a baseline and makes sure we don't get into an
16684        // infinite recursion.
16685        app.adjSeq = mAdjSeq;
16686        app.curRawAdj = adj;
16687        app.hasStartedServices = false;
16688
16689        if (mBackupTarget != null && app == mBackupTarget.app) {
16690            // If possible we want to avoid killing apps while they're being backed up
16691            if (adj > ProcessList.BACKUP_APP_ADJ) {
16692                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16693                adj = ProcessList.BACKUP_APP_ADJ;
16694                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16695                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16696                }
16697                app.adjType = "backup";
16698                app.cached = false;
16699            }
16700            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16701                procState = ActivityManager.PROCESS_STATE_BACKUP;
16702            }
16703        }
16704
16705        boolean mayBeTop = false;
16706
16707        for (int is = app.services.size()-1;
16708                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16709                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16710                        || procState > ActivityManager.PROCESS_STATE_TOP);
16711                is--) {
16712            ServiceRecord s = app.services.valueAt(is);
16713            if (s.startRequested) {
16714                app.hasStartedServices = true;
16715                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16716                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16717                }
16718                if (app.hasShownUi && app != mHomeProcess) {
16719                    // If this process has shown some UI, let it immediately
16720                    // go to the LRU list because it may be pretty heavy with
16721                    // UI stuff.  We'll tag it with a label just to help
16722                    // debug and understand what is going on.
16723                    if (adj > ProcessList.SERVICE_ADJ) {
16724                        app.adjType = "cch-started-ui-services";
16725                    }
16726                } else {
16727                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16728                        // This service has seen some activity within
16729                        // recent memory, so we will keep its process ahead
16730                        // of the background processes.
16731                        if (adj > ProcessList.SERVICE_ADJ) {
16732                            adj = ProcessList.SERVICE_ADJ;
16733                            app.adjType = "started-services";
16734                            app.cached = false;
16735                        }
16736                    }
16737                    // If we have let the service slide into the background
16738                    // state, still have some text describing what it is doing
16739                    // even though the service no longer has an impact.
16740                    if (adj > ProcessList.SERVICE_ADJ) {
16741                        app.adjType = "cch-started-services";
16742                    }
16743                }
16744            }
16745            for (int conni = s.connections.size()-1;
16746                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16747                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16748                            || procState > ActivityManager.PROCESS_STATE_TOP);
16749                    conni--) {
16750                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16751                for (int i = 0;
16752                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16753                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16754                                || procState > ActivityManager.PROCESS_STATE_TOP);
16755                        i++) {
16756                    // XXX should compute this based on the max of
16757                    // all connected clients.
16758                    ConnectionRecord cr = clist.get(i);
16759                    if (cr.binding.client == app) {
16760                        // Binding to ourself is not interesting.
16761                        continue;
16762                    }
16763                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16764                        ProcessRecord client = cr.binding.client;
16765                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16766                                TOP_APP, doingAll, now);
16767                        int clientProcState = client.curProcState;
16768                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16769                            // If the other app is cached for any reason, for purposes here
16770                            // we are going to consider it empty.  The specific cached state
16771                            // doesn't propagate except under certain conditions.
16772                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16773                        }
16774                        String adjType = null;
16775                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16776                            // Not doing bind OOM management, so treat
16777                            // this guy more like a started service.
16778                            if (app.hasShownUi && app != mHomeProcess) {
16779                                // If this process has shown some UI, let it immediately
16780                                // go to the LRU list because it may be pretty heavy with
16781                                // UI stuff.  We'll tag it with a label just to help
16782                                // debug and understand what is going on.
16783                                if (adj > clientAdj) {
16784                                    adjType = "cch-bound-ui-services";
16785                                }
16786                                app.cached = false;
16787                                clientAdj = adj;
16788                                clientProcState = procState;
16789                            } else {
16790                                if (now >= (s.lastActivity
16791                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16792                                    // This service has not seen activity within
16793                                    // recent memory, so allow it to drop to the
16794                                    // LRU list if there is no other reason to keep
16795                                    // it around.  We'll also tag it with a label just
16796                                    // to help debug and undertand what is going on.
16797                                    if (adj > clientAdj) {
16798                                        adjType = "cch-bound-services";
16799                                    }
16800                                    clientAdj = adj;
16801                                }
16802                            }
16803                        }
16804                        if (adj > clientAdj) {
16805                            // If this process has recently shown UI, and
16806                            // the process that is binding to it is less
16807                            // important than being visible, then we don't
16808                            // care about the binding as much as we care
16809                            // about letting this process get into the LRU
16810                            // list to be killed and restarted if needed for
16811                            // memory.
16812                            if (app.hasShownUi && app != mHomeProcess
16813                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16814                                adjType = "cch-bound-ui-services";
16815                            } else {
16816                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16817                                        |Context.BIND_IMPORTANT)) != 0) {
16818                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16819                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16820                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16821                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16822                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16823                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16824                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16825                                    adj = clientAdj;
16826                                } else {
16827                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16828                                        adj = ProcessList.VISIBLE_APP_ADJ;
16829                                    }
16830                                }
16831                                if (!client.cached) {
16832                                    app.cached = false;
16833                                }
16834                                adjType = "service";
16835                            }
16836                        }
16837                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16838                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16839                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16840                            }
16841                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16842                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16843                                    // Special handling of clients who are in the top state.
16844                                    // We *may* want to consider this process to be in the
16845                                    // top state as well, but only if there is not another
16846                                    // reason for it to be running.  Being on the top is a
16847                                    // special state, meaning you are specifically running
16848                                    // for the current top app.  If the process is already
16849                                    // running in the background for some other reason, it
16850                                    // is more important to continue considering it to be
16851                                    // in the background state.
16852                                    mayBeTop = true;
16853                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16854                                } else {
16855                                    // Special handling for above-top states (persistent
16856                                    // processes).  These should not bring the current process
16857                                    // into the top state, since they are not on top.  Instead
16858                                    // give them the best state after that.
16859                                    clientProcState =
16860                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16861                                }
16862                            }
16863                        } else {
16864                            if (clientProcState <
16865                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16866                                clientProcState =
16867                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16868                            }
16869                        }
16870                        if (procState > clientProcState) {
16871                            procState = clientProcState;
16872                        }
16873                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16874                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16875                            app.pendingUiClean = true;
16876                        }
16877                        if (adjType != null) {
16878                            app.adjType = adjType;
16879                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16880                                    .REASON_SERVICE_IN_USE;
16881                            app.adjSource = cr.binding.client;
16882                            app.adjSourceProcState = clientProcState;
16883                            app.adjTarget = s.name;
16884                        }
16885                    }
16886                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16887                        app.treatLikeActivity = true;
16888                    }
16889                    final ActivityRecord a = cr.activity;
16890                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16891                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16892                                (a.visible || a.state == ActivityState.RESUMED
16893                                 || a.state == ActivityState.PAUSING)) {
16894                            adj = ProcessList.FOREGROUND_APP_ADJ;
16895                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16896                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16897                            }
16898                            app.cached = false;
16899                            app.adjType = "service";
16900                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16901                                    .REASON_SERVICE_IN_USE;
16902                            app.adjSource = a;
16903                            app.adjSourceProcState = procState;
16904                            app.adjTarget = s.name;
16905                        }
16906                    }
16907                }
16908            }
16909        }
16910
16911        for (int provi = app.pubProviders.size()-1;
16912                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16913                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16914                        || procState > ActivityManager.PROCESS_STATE_TOP);
16915                provi--) {
16916            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16917            for (int i = cpr.connections.size()-1;
16918                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16919                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16920                            || procState > ActivityManager.PROCESS_STATE_TOP);
16921                    i--) {
16922                ContentProviderConnection conn = cpr.connections.get(i);
16923                ProcessRecord client = conn.client;
16924                if (client == app) {
16925                    // Being our own client is not interesting.
16926                    continue;
16927                }
16928                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16929                int clientProcState = client.curProcState;
16930                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16931                    // If the other app is cached for any reason, for purposes here
16932                    // we are going to consider it empty.
16933                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16934                }
16935                if (adj > clientAdj) {
16936                    if (app.hasShownUi && app != mHomeProcess
16937                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16938                        app.adjType = "cch-ui-provider";
16939                    } else {
16940                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16941                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16942                        app.adjType = "provider";
16943                    }
16944                    app.cached &= client.cached;
16945                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16946                            .REASON_PROVIDER_IN_USE;
16947                    app.adjSource = client;
16948                    app.adjSourceProcState = clientProcState;
16949                    app.adjTarget = cpr.name;
16950                }
16951                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16952                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16953                        // Special handling of clients who are in the top state.
16954                        // We *may* want to consider this process to be in the
16955                        // top state as well, but only if there is not another
16956                        // reason for it to be running.  Being on the top is a
16957                        // special state, meaning you are specifically running
16958                        // for the current top app.  If the process is already
16959                        // running in the background for some other reason, it
16960                        // is more important to continue considering it to be
16961                        // in the background state.
16962                        mayBeTop = true;
16963                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16964                    } else {
16965                        // Special handling for above-top states (persistent
16966                        // processes).  These should not bring the current process
16967                        // into the top state, since they are not on top.  Instead
16968                        // give them the best state after that.
16969                        clientProcState =
16970                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16971                    }
16972                }
16973                if (procState > clientProcState) {
16974                    procState = clientProcState;
16975                }
16976                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16977                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16978                }
16979            }
16980            // If the provider has external (non-framework) process
16981            // dependencies, ensure that its adjustment is at least
16982            // FOREGROUND_APP_ADJ.
16983            if (cpr.hasExternalProcessHandles()) {
16984                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16985                    adj = ProcessList.FOREGROUND_APP_ADJ;
16986                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16987                    app.cached = false;
16988                    app.adjType = "provider";
16989                    app.adjTarget = cpr.name;
16990                }
16991                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16992                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16993                }
16994            }
16995        }
16996
16997        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16998            // A client of one of our services or providers is in the top state.  We
16999            // *may* want to be in the top state, but not if we are already running in
17000            // the background for some other reason.  For the decision here, we are going
17001            // to pick out a few specific states that we want to remain in when a client
17002            // is top (states that tend to be longer-term) and otherwise allow it to go
17003            // to the top state.
17004            switch (procState) {
17005                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17006                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17007                case ActivityManager.PROCESS_STATE_SERVICE:
17008                    // These all are longer-term states, so pull them up to the top
17009                    // of the background states, but not all the way to the top state.
17010                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17011                    break;
17012                default:
17013                    // Otherwise, top is a better choice, so take it.
17014                    procState = ActivityManager.PROCESS_STATE_TOP;
17015                    break;
17016            }
17017        }
17018
17019        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17020            if (app.hasClientActivities) {
17021                // This is a cached process, but with client activities.  Mark it so.
17022                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17023                app.adjType = "cch-client-act";
17024            } else if (app.treatLikeActivity) {
17025                // This is a cached process, but somebody wants us to treat it like it has
17026                // an activity, okay!
17027                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17028                app.adjType = "cch-as-act";
17029            }
17030        }
17031
17032        if (adj == ProcessList.SERVICE_ADJ) {
17033            if (doingAll) {
17034                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17035                mNewNumServiceProcs++;
17036                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17037                if (!app.serviceb) {
17038                    // This service isn't far enough down on the LRU list to
17039                    // normally be a B service, but if we are low on RAM and it
17040                    // is large we want to force it down since we would prefer to
17041                    // keep launcher over it.
17042                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17043                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17044                        app.serviceHighRam = true;
17045                        app.serviceb = true;
17046                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17047                    } else {
17048                        mNewNumAServiceProcs++;
17049                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17050                    }
17051                } else {
17052                    app.serviceHighRam = false;
17053                }
17054            }
17055            if (app.serviceb) {
17056                adj = ProcessList.SERVICE_B_ADJ;
17057            }
17058        }
17059
17060        app.curRawAdj = adj;
17061
17062        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17063        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17064        if (adj > app.maxAdj) {
17065            adj = app.maxAdj;
17066            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17067                schedGroup = Process.THREAD_GROUP_DEFAULT;
17068            }
17069        }
17070
17071        // Do final modification to adj.  Everything we do between here and applying
17072        // the final setAdj must be done in this function, because we will also use
17073        // it when computing the final cached adj later.  Note that we don't need to
17074        // worry about this for max adj above, since max adj will always be used to
17075        // keep it out of the cached vaues.
17076        app.curAdj = app.modifyRawOomAdj(adj);
17077        app.curSchedGroup = schedGroup;
17078        app.curProcState = procState;
17079        app.foregroundActivities = foregroundActivities;
17080
17081        return app.curRawAdj;
17082    }
17083
17084    /**
17085     * Schedule PSS collection of a process.
17086     */
17087    void requestPssLocked(ProcessRecord proc, int procState) {
17088        if (mPendingPssProcesses.contains(proc)) {
17089            return;
17090        }
17091        if (mPendingPssProcesses.size() == 0) {
17092            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17093        }
17094        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17095        proc.pssProcState = procState;
17096        mPendingPssProcesses.add(proc);
17097    }
17098
17099    /**
17100     * Schedule PSS collection of all processes.
17101     */
17102    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17103        if (!always) {
17104            if (now < (mLastFullPssTime +
17105                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17106                return;
17107            }
17108        }
17109        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17110        mLastFullPssTime = now;
17111        mFullPssPending = true;
17112        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17113        mPendingPssProcesses.clear();
17114        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17115            ProcessRecord app = mLruProcesses.get(i);
17116            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17117                app.pssProcState = app.setProcState;
17118                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17119                        isSleeping(), now);
17120                mPendingPssProcesses.add(app);
17121            }
17122        }
17123        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17124    }
17125
17126    /**
17127     * Ask a given process to GC right now.
17128     */
17129    final void performAppGcLocked(ProcessRecord app) {
17130        try {
17131            app.lastRequestedGc = SystemClock.uptimeMillis();
17132            if (app.thread != null) {
17133                if (app.reportLowMemory) {
17134                    app.reportLowMemory = false;
17135                    app.thread.scheduleLowMemory();
17136                } else {
17137                    app.thread.processInBackground();
17138                }
17139            }
17140        } catch (Exception e) {
17141            // whatever.
17142        }
17143    }
17144
17145    /**
17146     * Returns true if things are idle enough to perform GCs.
17147     */
17148    private final boolean canGcNowLocked() {
17149        boolean processingBroadcasts = false;
17150        for (BroadcastQueue q : mBroadcastQueues) {
17151            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17152                processingBroadcasts = true;
17153            }
17154        }
17155        return !processingBroadcasts
17156                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17157    }
17158
17159    /**
17160     * Perform GCs on all processes that are waiting for it, but only
17161     * if things are idle.
17162     */
17163    final void performAppGcsLocked() {
17164        final int N = mProcessesToGc.size();
17165        if (N <= 0) {
17166            return;
17167        }
17168        if (canGcNowLocked()) {
17169            while (mProcessesToGc.size() > 0) {
17170                ProcessRecord proc = mProcessesToGc.remove(0);
17171                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17172                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17173                            <= SystemClock.uptimeMillis()) {
17174                        // To avoid spamming the system, we will GC processes one
17175                        // at a time, waiting a few seconds between each.
17176                        performAppGcLocked(proc);
17177                        scheduleAppGcsLocked();
17178                        return;
17179                    } else {
17180                        // It hasn't been long enough since we last GCed this
17181                        // process...  put it in the list to wait for its time.
17182                        addProcessToGcListLocked(proc);
17183                        break;
17184                    }
17185                }
17186            }
17187
17188            scheduleAppGcsLocked();
17189        }
17190    }
17191
17192    /**
17193     * If all looks good, perform GCs on all processes waiting for them.
17194     */
17195    final void performAppGcsIfAppropriateLocked() {
17196        if (canGcNowLocked()) {
17197            performAppGcsLocked();
17198            return;
17199        }
17200        // Still not idle, wait some more.
17201        scheduleAppGcsLocked();
17202    }
17203
17204    /**
17205     * Schedule the execution of all pending app GCs.
17206     */
17207    final void scheduleAppGcsLocked() {
17208        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17209
17210        if (mProcessesToGc.size() > 0) {
17211            // Schedule a GC for the time to the next process.
17212            ProcessRecord proc = mProcessesToGc.get(0);
17213            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17214
17215            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17216            long now = SystemClock.uptimeMillis();
17217            if (when < (now+GC_TIMEOUT)) {
17218                when = now + GC_TIMEOUT;
17219            }
17220            mHandler.sendMessageAtTime(msg, when);
17221        }
17222    }
17223
17224    /**
17225     * Add a process to the array of processes waiting to be GCed.  Keeps the
17226     * list in sorted order by the last GC time.  The process can't already be
17227     * on the list.
17228     */
17229    final void addProcessToGcListLocked(ProcessRecord proc) {
17230        boolean added = false;
17231        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17232            if (mProcessesToGc.get(i).lastRequestedGc <
17233                    proc.lastRequestedGc) {
17234                added = true;
17235                mProcessesToGc.add(i+1, proc);
17236                break;
17237            }
17238        }
17239        if (!added) {
17240            mProcessesToGc.add(0, proc);
17241        }
17242    }
17243
17244    /**
17245     * Set up to ask a process to GC itself.  This will either do it
17246     * immediately, or put it on the list of processes to gc the next
17247     * time things are idle.
17248     */
17249    final void scheduleAppGcLocked(ProcessRecord app) {
17250        long now = SystemClock.uptimeMillis();
17251        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17252            return;
17253        }
17254        if (!mProcessesToGc.contains(app)) {
17255            addProcessToGcListLocked(app);
17256            scheduleAppGcsLocked();
17257        }
17258    }
17259
17260    final void checkExcessivePowerUsageLocked(boolean doKills) {
17261        updateCpuStatsNow();
17262
17263        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17264        boolean doWakeKills = doKills;
17265        boolean doCpuKills = doKills;
17266        if (mLastPowerCheckRealtime == 0) {
17267            doWakeKills = false;
17268        }
17269        if (mLastPowerCheckUptime == 0) {
17270            doCpuKills = false;
17271        }
17272        if (stats.isScreenOn()) {
17273            doWakeKills = false;
17274        }
17275        final long curRealtime = SystemClock.elapsedRealtime();
17276        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17277        final long curUptime = SystemClock.uptimeMillis();
17278        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17279        mLastPowerCheckRealtime = curRealtime;
17280        mLastPowerCheckUptime = curUptime;
17281        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17282            doWakeKills = false;
17283        }
17284        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17285            doCpuKills = false;
17286        }
17287        int i = mLruProcesses.size();
17288        while (i > 0) {
17289            i--;
17290            ProcessRecord app = mLruProcesses.get(i);
17291            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17292                long wtime;
17293                synchronized (stats) {
17294                    wtime = stats.getProcessWakeTime(app.info.uid,
17295                            app.pid, curRealtime);
17296                }
17297                long wtimeUsed = wtime - app.lastWakeTime;
17298                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17299                if (DEBUG_POWER) {
17300                    StringBuilder sb = new StringBuilder(128);
17301                    sb.append("Wake for ");
17302                    app.toShortString(sb);
17303                    sb.append(": over ");
17304                    TimeUtils.formatDuration(realtimeSince, sb);
17305                    sb.append(" used ");
17306                    TimeUtils.formatDuration(wtimeUsed, sb);
17307                    sb.append(" (");
17308                    sb.append((wtimeUsed*100)/realtimeSince);
17309                    sb.append("%)");
17310                    Slog.i(TAG, sb.toString());
17311                    sb.setLength(0);
17312                    sb.append("CPU for ");
17313                    app.toShortString(sb);
17314                    sb.append(": over ");
17315                    TimeUtils.formatDuration(uptimeSince, sb);
17316                    sb.append(" used ");
17317                    TimeUtils.formatDuration(cputimeUsed, sb);
17318                    sb.append(" (");
17319                    sb.append((cputimeUsed*100)/uptimeSince);
17320                    sb.append("%)");
17321                    Slog.i(TAG, sb.toString());
17322                }
17323                // If a process has held a wake lock for more
17324                // than 50% of the time during this period,
17325                // that sounds bad.  Kill!
17326                if (doWakeKills && realtimeSince > 0
17327                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17328                    synchronized (stats) {
17329                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17330                                realtimeSince, wtimeUsed);
17331                    }
17332                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17333                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17334                } else if (doCpuKills && uptimeSince > 0
17335                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17336                    synchronized (stats) {
17337                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17338                                uptimeSince, cputimeUsed);
17339                    }
17340                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17341                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17342                } else {
17343                    app.lastWakeTime = wtime;
17344                    app.lastCpuTime = app.curCpuTime;
17345                }
17346            }
17347        }
17348    }
17349
17350    private final boolean applyOomAdjLocked(ProcessRecord app,
17351            ProcessRecord TOP_APP, boolean doingAll, long now) {
17352        boolean success = true;
17353
17354        if (app.curRawAdj != app.setRawAdj) {
17355            app.setRawAdj = app.curRawAdj;
17356        }
17357
17358        int changes = 0;
17359
17360        if (app.curAdj != app.setAdj) {
17361            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17362            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17363                TAG, "Set " + app.pid + " " + app.processName +
17364                " adj " + app.curAdj + ": " + app.adjType);
17365            app.setAdj = app.curAdj;
17366        }
17367
17368        if (app.setSchedGroup != app.curSchedGroup) {
17369            app.setSchedGroup = app.curSchedGroup;
17370            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17371                    "Setting process group of " + app.processName
17372                    + " to " + app.curSchedGroup);
17373            if (app.waitingToKill != null &&
17374                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17375                app.kill(app.waitingToKill, true);
17376                success = false;
17377            } else {
17378                if (true) {
17379                    long oldId = Binder.clearCallingIdentity();
17380                    try {
17381                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17382                    } catch (Exception e) {
17383                        Slog.w(TAG, "Failed setting process group of " + app.pid
17384                                + " to " + app.curSchedGroup);
17385                        e.printStackTrace();
17386                    } finally {
17387                        Binder.restoreCallingIdentity(oldId);
17388                    }
17389                } else {
17390                    if (app.thread != null) {
17391                        try {
17392                            app.thread.setSchedulingGroup(app.curSchedGroup);
17393                        } catch (RemoteException e) {
17394                        }
17395                    }
17396                }
17397                Process.setSwappiness(app.pid,
17398                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17399            }
17400        }
17401        if (app.repForegroundActivities != app.foregroundActivities) {
17402            app.repForegroundActivities = app.foregroundActivities;
17403            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17404        }
17405        if (app.repProcState != app.curProcState) {
17406            app.repProcState = app.curProcState;
17407            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17408            if (app.thread != null) {
17409                try {
17410                    if (false) {
17411                        //RuntimeException h = new RuntimeException("here");
17412                        Slog.i(TAG, "Sending new process state " + app.repProcState
17413                                + " to " + app /*, h*/);
17414                    }
17415                    app.thread.setProcessState(app.repProcState);
17416                } catch (RemoteException e) {
17417                }
17418            }
17419        }
17420        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17421                app.setProcState)) {
17422            app.lastStateTime = now;
17423            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17424                    isSleeping(), now);
17425            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17426                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17427                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17428                    + (app.nextPssTime-now) + ": " + app);
17429        } else {
17430            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17431                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17432                requestPssLocked(app, app.setProcState);
17433                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17434                        isSleeping(), now);
17435            } else if (false && DEBUG_PSS) {
17436                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17437            }
17438        }
17439        if (app.setProcState != app.curProcState) {
17440            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17441                    "Proc state change of " + app.processName
17442                    + " to " + app.curProcState);
17443            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17444            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17445            if (setImportant && !curImportant) {
17446                // This app is no longer something we consider important enough to allow to
17447                // use arbitrary amounts of battery power.  Note
17448                // its current wake lock time to later know to kill it if
17449                // it is not behaving well.
17450                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17451                synchronized (stats) {
17452                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17453                            app.pid, SystemClock.elapsedRealtime());
17454                }
17455                app.lastCpuTime = app.curCpuTime;
17456
17457            }
17458            app.setProcState = app.curProcState;
17459            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17460                app.notCachedSinceIdle = false;
17461            }
17462            if (!doingAll) {
17463                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17464            } else {
17465                app.procStateChanged = true;
17466            }
17467        }
17468
17469        if (changes != 0) {
17470            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17471            int i = mPendingProcessChanges.size()-1;
17472            ProcessChangeItem item = null;
17473            while (i >= 0) {
17474                item = mPendingProcessChanges.get(i);
17475                if (item.pid == app.pid) {
17476                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17477                    break;
17478                }
17479                i--;
17480            }
17481            if (i < 0) {
17482                // No existing item in pending changes; need a new one.
17483                final int NA = mAvailProcessChanges.size();
17484                if (NA > 0) {
17485                    item = mAvailProcessChanges.remove(NA-1);
17486                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17487                } else {
17488                    item = new ProcessChangeItem();
17489                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17490                }
17491                item.changes = 0;
17492                item.pid = app.pid;
17493                item.uid = app.info.uid;
17494                if (mPendingProcessChanges.size() == 0) {
17495                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17496                            "*** Enqueueing dispatch processes changed!");
17497                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17498                }
17499                mPendingProcessChanges.add(item);
17500            }
17501            item.changes |= changes;
17502            item.processState = app.repProcState;
17503            item.foregroundActivities = app.repForegroundActivities;
17504            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17505                    + Integer.toHexString(System.identityHashCode(item))
17506                    + " " + app.toShortString() + ": changes=" + item.changes
17507                    + " procState=" + item.processState
17508                    + " foreground=" + item.foregroundActivities
17509                    + " type=" + app.adjType + " source=" + app.adjSource
17510                    + " target=" + app.adjTarget);
17511        }
17512
17513        return success;
17514    }
17515
17516    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17517        if (proc.thread != null) {
17518            if (proc.baseProcessTracker != null) {
17519                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17520            }
17521            if (proc.repProcState >= 0) {
17522                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17523                        proc.repProcState);
17524            }
17525        }
17526    }
17527
17528    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17529            ProcessRecord TOP_APP, boolean doingAll, long now) {
17530        if (app.thread == null) {
17531            return false;
17532        }
17533
17534        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17535
17536        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17537    }
17538
17539    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17540            boolean oomAdj) {
17541        if (isForeground != proc.foregroundServices) {
17542            proc.foregroundServices = isForeground;
17543            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17544                    proc.info.uid);
17545            if (isForeground) {
17546                if (curProcs == null) {
17547                    curProcs = new ArrayList<ProcessRecord>();
17548                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17549                }
17550                if (!curProcs.contains(proc)) {
17551                    curProcs.add(proc);
17552                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17553                            proc.info.packageName, proc.info.uid);
17554                }
17555            } else {
17556                if (curProcs != null) {
17557                    if (curProcs.remove(proc)) {
17558                        mBatteryStatsService.noteEvent(
17559                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17560                                proc.info.packageName, proc.info.uid);
17561                        if (curProcs.size() <= 0) {
17562                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17563                        }
17564                    }
17565                }
17566            }
17567            if (oomAdj) {
17568                updateOomAdjLocked();
17569            }
17570        }
17571    }
17572
17573    private final ActivityRecord resumedAppLocked() {
17574        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17575        String pkg;
17576        int uid;
17577        if (act != null) {
17578            pkg = act.packageName;
17579            uid = act.info.applicationInfo.uid;
17580        } else {
17581            pkg = null;
17582            uid = -1;
17583        }
17584        // Has the UID or resumed package name changed?
17585        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17586                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17587            if (mCurResumedPackage != null) {
17588                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17589                        mCurResumedPackage, mCurResumedUid);
17590            }
17591            mCurResumedPackage = pkg;
17592            mCurResumedUid = uid;
17593            if (mCurResumedPackage != null) {
17594                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17595                        mCurResumedPackage, mCurResumedUid);
17596            }
17597        }
17598        return act;
17599    }
17600
17601    final boolean updateOomAdjLocked(ProcessRecord app) {
17602        final ActivityRecord TOP_ACT = resumedAppLocked();
17603        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17604        final boolean wasCached = app.cached;
17605
17606        mAdjSeq++;
17607
17608        // This is the desired cached adjusment we want to tell it to use.
17609        // If our app is currently cached, we know it, and that is it.  Otherwise,
17610        // we don't know it yet, and it needs to now be cached we will then
17611        // need to do a complete oom adj.
17612        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17613                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17614        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17615                SystemClock.uptimeMillis());
17616        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17617            // Changed to/from cached state, so apps after it in the LRU
17618            // list may also be changed.
17619            updateOomAdjLocked();
17620        }
17621        return success;
17622    }
17623
17624    final void updateOomAdjLocked() {
17625        final ActivityRecord TOP_ACT = resumedAppLocked();
17626        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17627        final long now = SystemClock.uptimeMillis();
17628        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17629        final int N = mLruProcesses.size();
17630
17631        if (false) {
17632            RuntimeException e = new RuntimeException();
17633            e.fillInStackTrace();
17634            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17635        }
17636
17637        mAdjSeq++;
17638        mNewNumServiceProcs = 0;
17639        mNewNumAServiceProcs = 0;
17640
17641        final int emptyProcessLimit;
17642        final int cachedProcessLimit;
17643        if (mProcessLimit <= 0) {
17644            emptyProcessLimit = cachedProcessLimit = 0;
17645        } else if (mProcessLimit == 1) {
17646            emptyProcessLimit = 1;
17647            cachedProcessLimit = 0;
17648        } else {
17649            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17650            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17651        }
17652
17653        // Let's determine how many processes we have running vs.
17654        // how many slots we have for background processes; we may want
17655        // to put multiple processes in a slot of there are enough of
17656        // them.
17657        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17658                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17659        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17660        if (numEmptyProcs > cachedProcessLimit) {
17661            // If there are more empty processes than our limit on cached
17662            // processes, then use the cached process limit for the factor.
17663            // This ensures that the really old empty processes get pushed
17664            // down to the bottom, so if we are running low on memory we will
17665            // have a better chance at keeping around more cached processes
17666            // instead of a gazillion empty processes.
17667            numEmptyProcs = cachedProcessLimit;
17668        }
17669        int emptyFactor = numEmptyProcs/numSlots;
17670        if (emptyFactor < 1) emptyFactor = 1;
17671        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17672        if (cachedFactor < 1) cachedFactor = 1;
17673        int stepCached = 0;
17674        int stepEmpty = 0;
17675        int numCached = 0;
17676        int numEmpty = 0;
17677        int numTrimming = 0;
17678
17679        mNumNonCachedProcs = 0;
17680        mNumCachedHiddenProcs = 0;
17681
17682        // First update the OOM adjustment for each of the
17683        // application processes based on their current state.
17684        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17685        int nextCachedAdj = curCachedAdj+1;
17686        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17687        int nextEmptyAdj = curEmptyAdj+2;
17688        for (int i=N-1; i>=0; i--) {
17689            ProcessRecord app = mLruProcesses.get(i);
17690            if (!app.killedByAm && app.thread != null) {
17691                app.procStateChanged = false;
17692                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17693
17694                // If we haven't yet assigned the final cached adj
17695                // to the process, do that now.
17696                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17697                    switch (app.curProcState) {
17698                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17699                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17700                            // This process is a cached process holding activities...
17701                            // assign it the next cached value for that type, and then
17702                            // step that cached level.
17703                            app.curRawAdj = curCachedAdj;
17704                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17705                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17706                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17707                                    + ")");
17708                            if (curCachedAdj != nextCachedAdj) {
17709                                stepCached++;
17710                                if (stepCached >= cachedFactor) {
17711                                    stepCached = 0;
17712                                    curCachedAdj = nextCachedAdj;
17713                                    nextCachedAdj += 2;
17714                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17715                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17716                                    }
17717                                }
17718                            }
17719                            break;
17720                        default:
17721                            // For everything else, assign next empty cached process
17722                            // level and bump that up.  Note that this means that
17723                            // long-running services that have dropped down to the
17724                            // cached level will be treated as empty (since their process
17725                            // state is still as a service), which is what we want.
17726                            app.curRawAdj = curEmptyAdj;
17727                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17728                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17729                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17730                                    + ")");
17731                            if (curEmptyAdj != nextEmptyAdj) {
17732                                stepEmpty++;
17733                                if (stepEmpty >= emptyFactor) {
17734                                    stepEmpty = 0;
17735                                    curEmptyAdj = nextEmptyAdj;
17736                                    nextEmptyAdj += 2;
17737                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17738                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17739                                    }
17740                                }
17741                            }
17742                            break;
17743                    }
17744                }
17745
17746                applyOomAdjLocked(app, TOP_APP, true, now);
17747
17748                // Count the number of process types.
17749                switch (app.curProcState) {
17750                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17751                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17752                        mNumCachedHiddenProcs++;
17753                        numCached++;
17754                        if (numCached > cachedProcessLimit) {
17755                            app.kill("cached #" + numCached, true);
17756                        }
17757                        break;
17758                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17759                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17760                                && app.lastActivityTime < oldTime) {
17761                            app.kill("empty for "
17762                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17763                                    / 1000) + "s", true);
17764                        } else {
17765                            numEmpty++;
17766                            if (numEmpty > emptyProcessLimit) {
17767                                app.kill("empty #" + numEmpty, true);
17768                            }
17769                        }
17770                        break;
17771                    default:
17772                        mNumNonCachedProcs++;
17773                        break;
17774                }
17775
17776                if (app.isolated && app.services.size() <= 0) {
17777                    // If this is an isolated process, and there are no
17778                    // services running in it, then the process is no longer
17779                    // needed.  We agressively kill these because we can by
17780                    // definition not re-use the same process again, and it is
17781                    // good to avoid having whatever code was running in them
17782                    // left sitting around after no longer needed.
17783                    app.kill("isolated not needed", true);
17784                }
17785
17786                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17787                        && !app.killedByAm) {
17788                    numTrimming++;
17789                }
17790            }
17791        }
17792
17793        mNumServiceProcs = mNewNumServiceProcs;
17794
17795        // Now determine the memory trimming level of background processes.
17796        // Unfortunately we need to start at the back of the list to do this
17797        // properly.  We only do this if the number of background apps we
17798        // are managing to keep around is less than half the maximum we desire;
17799        // if we are keeping a good number around, we'll let them use whatever
17800        // memory they want.
17801        final int numCachedAndEmpty = numCached + numEmpty;
17802        int memFactor;
17803        if (numCached <= ProcessList.TRIM_CACHED_APPS
17804                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17805            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17806                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17807            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17808                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17809            } else {
17810                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17811            }
17812        } else {
17813            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17814        }
17815        // We always allow the memory level to go up (better).  We only allow it to go
17816        // down if we are in a state where that is allowed, *and* the total number of processes
17817        // has gone down since last time.
17818        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17819                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17820                + " last=" + mLastNumProcesses);
17821        if (memFactor > mLastMemoryLevel) {
17822            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17823                memFactor = mLastMemoryLevel;
17824                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17825            }
17826        }
17827        mLastMemoryLevel = memFactor;
17828        mLastNumProcesses = mLruProcesses.size();
17829        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17830        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17831        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17832            if (mLowRamStartTime == 0) {
17833                mLowRamStartTime = now;
17834            }
17835            int step = 0;
17836            int fgTrimLevel;
17837            switch (memFactor) {
17838                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17839                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17840                    break;
17841                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17842                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17843                    break;
17844                default:
17845                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17846                    break;
17847            }
17848            int factor = numTrimming/3;
17849            int minFactor = 2;
17850            if (mHomeProcess != null) minFactor++;
17851            if (mPreviousProcess != null) minFactor++;
17852            if (factor < minFactor) factor = minFactor;
17853            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17854            for (int i=N-1; i>=0; i--) {
17855                ProcessRecord app = mLruProcesses.get(i);
17856                if (allChanged || app.procStateChanged) {
17857                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17858                    app.procStateChanged = false;
17859                }
17860                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17861                        && !app.killedByAm) {
17862                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17863                        try {
17864                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17865                                    "Trimming memory of " + app.processName
17866                                    + " to " + curLevel);
17867                            app.thread.scheduleTrimMemory(curLevel);
17868                        } catch (RemoteException e) {
17869                        }
17870                        if (false) {
17871                            // For now we won't do this; our memory trimming seems
17872                            // to be good enough at this point that destroying
17873                            // activities causes more harm than good.
17874                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17875                                    && app != mHomeProcess && app != mPreviousProcess) {
17876                                // Need to do this on its own message because the stack may not
17877                                // be in a consistent state at this point.
17878                                // For these apps we will also finish their activities
17879                                // to help them free memory.
17880                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17881                            }
17882                        }
17883                    }
17884                    app.trimMemoryLevel = curLevel;
17885                    step++;
17886                    if (step >= factor) {
17887                        step = 0;
17888                        switch (curLevel) {
17889                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17890                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17891                                break;
17892                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17893                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17894                                break;
17895                        }
17896                    }
17897                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17898                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17899                            && app.thread != null) {
17900                        try {
17901                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17902                                    "Trimming memory of heavy-weight " + app.processName
17903                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17904                            app.thread.scheduleTrimMemory(
17905                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17906                        } catch (RemoteException e) {
17907                        }
17908                    }
17909                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17910                } else {
17911                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17912                            || app.systemNoUi) && app.pendingUiClean) {
17913                        // If this application is now in the background and it
17914                        // had done UI, then give it the special trim level to
17915                        // have it free UI resources.
17916                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17917                        if (app.trimMemoryLevel < level && app.thread != null) {
17918                            try {
17919                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17920                                        "Trimming memory of bg-ui " + app.processName
17921                                        + " to " + level);
17922                                app.thread.scheduleTrimMemory(level);
17923                            } catch (RemoteException e) {
17924                            }
17925                        }
17926                        app.pendingUiClean = false;
17927                    }
17928                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17929                        try {
17930                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17931                                    "Trimming memory of fg " + app.processName
17932                                    + " to " + fgTrimLevel);
17933                            app.thread.scheduleTrimMemory(fgTrimLevel);
17934                        } catch (RemoteException e) {
17935                        }
17936                    }
17937                    app.trimMemoryLevel = fgTrimLevel;
17938                }
17939            }
17940        } else {
17941            if (mLowRamStartTime != 0) {
17942                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17943                mLowRamStartTime = 0;
17944            }
17945            for (int i=N-1; i>=0; i--) {
17946                ProcessRecord app = mLruProcesses.get(i);
17947                if (allChanged || app.procStateChanged) {
17948                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17949                    app.procStateChanged = false;
17950                }
17951                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17952                        || app.systemNoUi) && app.pendingUiClean) {
17953                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17954                            && app.thread != null) {
17955                        try {
17956                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17957                                    "Trimming memory of ui hidden " + app.processName
17958                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17959                            app.thread.scheduleTrimMemory(
17960                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17961                        } catch (RemoteException e) {
17962                        }
17963                    }
17964                    app.pendingUiClean = false;
17965                }
17966                app.trimMemoryLevel = 0;
17967            }
17968        }
17969
17970        if (mAlwaysFinishActivities) {
17971            // Need to do this on its own message because the stack may not
17972            // be in a consistent state at this point.
17973            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17974        }
17975
17976        if (allChanged) {
17977            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17978        }
17979
17980        if (mProcessStats.shouldWriteNowLocked(now)) {
17981            mHandler.post(new Runnable() {
17982                @Override public void run() {
17983                    synchronized (ActivityManagerService.this) {
17984                        mProcessStats.writeStateAsyncLocked();
17985                    }
17986                }
17987            });
17988        }
17989
17990        if (DEBUG_OOM_ADJ) {
17991            if (false) {
17992                RuntimeException here = new RuntimeException("here");
17993                here.fillInStackTrace();
17994                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17995            } else {
17996                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17997            }
17998        }
17999    }
18000
18001    final void trimApplications() {
18002        synchronized (this) {
18003            int i;
18004
18005            // First remove any unused application processes whose package
18006            // has been removed.
18007            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18008                final ProcessRecord app = mRemovedProcesses.get(i);
18009                if (app.activities.size() == 0
18010                        && app.curReceiver == null && app.services.size() == 0) {
18011                    Slog.i(
18012                        TAG, "Exiting empty application process "
18013                        + app.processName + " ("
18014                        + (app.thread != null ? app.thread.asBinder() : null)
18015                        + ")\n");
18016                    if (app.pid > 0 && app.pid != MY_PID) {
18017                        app.kill("empty", false);
18018                    } else {
18019                        try {
18020                            app.thread.scheduleExit();
18021                        } catch (Exception e) {
18022                            // Ignore exceptions.
18023                        }
18024                    }
18025                    cleanUpApplicationRecordLocked(app, false, true, -1);
18026                    mRemovedProcesses.remove(i);
18027
18028                    if (app.persistent) {
18029                        addAppLocked(app.info, false, null /* ABI override */);
18030                    }
18031                }
18032            }
18033
18034            // Now update the oom adj for all processes.
18035            updateOomAdjLocked();
18036        }
18037    }
18038
18039    /** This method sends the specified signal to each of the persistent apps */
18040    public void signalPersistentProcesses(int sig) throws RemoteException {
18041        if (sig != Process.SIGNAL_USR1) {
18042            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18043        }
18044
18045        synchronized (this) {
18046            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18047                    != PackageManager.PERMISSION_GRANTED) {
18048                throw new SecurityException("Requires permission "
18049                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18050            }
18051
18052            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18053                ProcessRecord r = mLruProcesses.get(i);
18054                if (r.thread != null && r.persistent) {
18055                    Process.sendSignal(r.pid, sig);
18056                }
18057            }
18058        }
18059    }
18060
18061    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18062        if (proc == null || proc == mProfileProc) {
18063            proc = mProfileProc;
18064            profileType = mProfileType;
18065            clearProfilerLocked();
18066        }
18067        if (proc == null) {
18068            return;
18069        }
18070        try {
18071            proc.thread.profilerControl(false, null, profileType);
18072        } catch (RemoteException e) {
18073            throw new IllegalStateException("Process disappeared");
18074        }
18075    }
18076
18077    private void clearProfilerLocked() {
18078        if (mProfileFd != null) {
18079            try {
18080                mProfileFd.close();
18081            } catch (IOException e) {
18082            }
18083        }
18084        mProfileApp = null;
18085        mProfileProc = null;
18086        mProfileFile = null;
18087        mProfileType = 0;
18088        mAutoStopProfiler = false;
18089        mSamplingInterval = 0;
18090    }
18091
18092    public boolean profileControl(String process, int userId, boolean start,
18093            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18094
18095        try {
18096            synchronized (this) {
18097                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18098                // its own permission.
18099                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18100                        != PackageManager.PERMISSION_GRANTED) {
18101                    throw new SecurityException("Requires permission "
18102                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18103                }
18104
18105                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18106                    throw new IllegalArgumentException("null profile info or fd");
18107                }
18108
18109                ProcessRecord proc = null;
18110                if (process != null) {
18111                    proc = findProcessLocked(process, userId, "profileControl");
18112                }
18113
18114                if (start && (proc == null || proc.thread == null)) {
18115                    throw new IllegalArgumentException("Unknown process: " + process);
18116                }
18117
18118                if (start) {
18119                    stopProfilerLocked(null, 0);
18120                    setProfileApp(proc.info, proc.processName, profilerInfo);
18121                    mProfileProc = proc;
18122                    mProfileType = profileType;
18123                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18124                    try {
18125                        fd = fd.dup();
18126                    } catch (IOException e) {
18127                        fd = null;
18128                    }
18129                    profilerInfo.profileFd = fd;
18130                    proc.thread.profilerControl(start, profilerInfo, profileType);
18131                    fd = null;
18132                    mProfileFd = null;
18133                } else {
18134                    stopProfilerLocked(proc, profileType);
18135                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18136                        try {
18137                            profilerInfo.profileFd.close();
18138                        } catch (IOException e) {
18139                        }
18140                    }
18141                }
18142
18143                return true;
18144            }
18145        } catch (RemoteException e) {
18146            throw new IllegalStateException("Process disappeared");
18147        } finally {
18148            if (profilerInfo != null && profilerInfo.profileFd != null) {
18149                try {
18150                    profilerInfo.profileFd.close();
18151                } catch (IOException e) {
18152                }
18153            }
18154        }
18155    }
18156
18157    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18158        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18159                userId, true, ALLOW_FULL_ONLY, callName, null);
18160        ProcessRecord proc = null;
18161        try {
18162            int pid = Integer.parseInt(process);
18163            synchronized (mPidsSelfLocked) {
18164                proc = mPidsSelfLocked.get(pid);
18165            }
18166        } catch (NumberFormatException e) {
18167        }
18168
18169        if (proc == null) {
18170            ArrayMap<String, SparseArray<ProcessRecord>> all
18171                    = mProcessNames.getMap();
18172            SparseArray<ProcessRecord> procs = all.get(process);
18173            if (procs != null && procs.size() > 0) {
18174                proc = procs.valueAt(0);
18175                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18176                    for (int i=1; i<procs.size(); i++) {
18177                        ProcessRecord thisProc = procs.valueAt(i);
18178                        if (thisProc.userId == userId) {
18179                            proc = thisProc;
18180                            break;
18181                        }
18182                    }
18183                }
18184            }
18185        }
18186
18187        return proc;
18188    }
18189
18190    public boolean dumpHeap(String process, int userId, boolean managed,
18191            String path, ParcelFileDescriptor fd) throws RemoteException {
18192
18193        try {
18194            synchronized (this) {
18195                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18196                // its own permission (same as profileControl).
18197                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18198                        != PackageManager.PERMISSION_GRANTED) {
18199                    throw new SecurityException("Requires permission "
18200                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18201                }
18202
18203                if (fd == null) {
18204                    throw new IllegalArgumentException("null fd");
18205                }
18206
18207                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18208                if (proc == null || proc.thread == null) {
18209                    throw new IllegalArgumentException("Unknown process: " + process);
18210                }
18211
18212                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18213                if (!isDebuggable) {
18214                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18215                        throw new SecurityException("Process not debuggable: " + proc);
18216                    }
18217                }
18218
18219                proc.thread.dumpHeap(managed, path, fd);
18220                fd = null;
18221                return true;
18222            }
18223        } catch (RemoteException e) {
18224            throw new IllegalStateException("Process disappeared");
18225        } finally {
18226            if (fd != null) {
18227                try {
18228                    fd.close();
18229                } catch (IOException e) {
18230                }
18231            }
18232        }
18233    }
18234
18235    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18236    public void monitor() {
18237        synchronized (this) { }
18238    }
18239
18240    void onCoreSettingsChange(Bundle settings) {
18241        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18242            ProcessRecord processRecord = mLruProcesses.get(i);
18243            try {
18244                if (processRecord.thread != null) {
18245                    processRecord.thread.setCoreSettings(settings);
18246                }
18247            } catch (RemoteException re) {
18248                /* ignore */
18249            }
18250        }
18251    }
18252
18253    // Multi-user methods
18254
18255    /**
18256     * Start user, if its not already running, but don't bring it to foreground.
18257     */
18258    @Override
18259    public boolean startUserInBackground(final int userId) {
18260        return startUser(userId, /* foreground */ false);
18261    }
18262
18263    /**
18264     * Start user, if its not already running, and bring it to foreground.
18265     */
18266    boolean startUserInForeground(final int userId, Dialog dlg) {
18267        boolean result = startUser(userId, /* foreground */ true);
18268        dlg.dismiss();
18269        return result;
18270    }
18271
18272    /**
18273     * Refreshes the list of users related to the current user when either a
18274     * user switch happens or when a new related user is started in the
18275     * background.
18276     */
18277    private void updateCurrentProfileIdsLocked() {
18278        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18279                mCurrentUserId, false /* enabledOnly */);
18280        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18281        for (int i = 0; i < currentProfileIds.length; i++) {
18282            currentProfileIds[i] = profiles.get(i).id;
18283        }
18284        mCurrentProfileIds = currentProfileIds;
18285
18286        synchronized (mUserProfileGroupIdsSelfLocked) {
18287            mUserProfileGroupIdsSelfLocked.clear();
18288            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18289            for (int i = 0; i < users.size(); i++) {
18290                UserInfo user = users.get(i);
18291                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18292                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18293                }
18294            }
18295        }
18296    }
18297
18298    private Set getProfileIdsLocked(int userId) {
18299        Set userIds = new HashSet<Integer>();
18300        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18301                userId, false /* enabledOnly */);
18302        for (UserInfo user : profiles) {
18303            userIds.add(Integer.valueOf(user.id));
18304        }
18305        return userIds;
18306    }
18307
18308    @Override
18309    public boolean switchUser(final int userId) {
18310        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18311        String userName;
18312        synchronized (this) {
18313            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18314            if (userInfo == null) {
18315                Slog.w(TAG, "No user info for user #" + userId);
18316                return false;
18317            }
18318            if (userInfo.isManagedProfile()) {
18319                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18320                return false;
18321            }
18322            userName = userInfo.name;
18323            mTargetUserId = userId;
18324        }
18325        mHandler.removeMessages(START_USER_SWITCH_MSG);
18326        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18327        return true;
18328    }
18329
18330    private void showUserSwitchDialog(int userId, String userName) {
18331        // The dialog will show and then initiate the user switch by calling startUserInForeground
18332        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18333                true /* above system */);
18334        d.show();
18335    }
18336
18337    private boolean startUser(final int userId, final boolean foreground) {
18338        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18339                != PackageManager.PERMISSION_GRANTED) {
18340            String msg = "Permission Denial: switchUser() from pid="
18341                    + Binder.getCallingPid()
18342                    + ", uid=" + Binder.getCallingUid()
18343                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18344            Slog.w(TAG, msg);
18345            throw new SecurityException(msg);
18346        }
18347
18348        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18349
18350        final long ident = Binder.clearCallingIdentity();
18351        try {
18352            synchronized (this) {
18353                final int oldUserId = mCurrentUserId;
18354                if (oldUserId == userId) {
18355                    return true;
18356                }
18357
18358                mStackSupervisor.setLockTaskModeLocked(null, false);
18359
18360                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18361                if (userInfo == null) {
18362                    Slog.w(TAG, "No user info for user #" + userId);
18363                    return false;
18364                }
18365                if (foreground && userInfo.isManagedProfile()) {
18366                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18367                    return false;
18368                }
18369
18370                if (foreground) {
18371                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18372                            R.anim.screen_user_enter);
18373                }
18374
18375                boolean needStart = false;
18376
18377                // If the user we are switching to is not currently started, then
18378                // we need to start it now.
18379                if (mStartedUsers.get(userId) == null) {
18380                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18381                    updateStartedUserArrayLocked();
18382                    needStart = true;
18383                }
18384
18385                final Integer userIdInt = Integer.valueOf(userId);
18386                mUserLru.remove(userIdInt);
18387                mUserLru.add(userIdInt);
18388
18389                if (foreground) {
18390                    mCurrentUserId = userId;
18391                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18392                    updateCurrentProfileIdsLocked();
18393                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18394                    // Once the internal notion of the active user has switched, we lock the device
18395                    // with the option to show the user switcher on the keyguard.
18396                    mWindowManager.lockNow(null);
18397                } else {
18398                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18399                    updateCurrentProfileIdsLocked();
18400                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18401                    mUserLru.remove(currentUserIdInt);
18402                    mUserLru.add(currentUserIdInt);
18403                }
18404
18405                final UserStartedState uss = mStartedUsers.get(userId);
18406
18407                // Make sure user is in the started state.  If it is currently
18408                // stopping, we need to knock that off.
18409                if (uss.mState == UserStartedState.STATE_STOPPING) {
18410                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18411                    // so we can just fairly silently bring the user back from
18412                    // the almost-dead.
18413                    uss.mState = UserStartedState.STATE_RUNNING;
18414                    updateStartedUserArrayLocked();
18415                    needStart = true;
18416                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18417                    // This means ACTION_SHUTDOWN has been sent, so we will
18418                    // need to treat this as a new boot of the user.
18419                    uss.mState = UserStartedState.STATE_BOOTING;
18420                    updateStartedUserArrayLocked();
18421                    needStart = true;
18422                }
18423
18424                if (uss.mState == UserStartedState.STATE_BOOTING) {
18425                    // Booting up a new user, need to tell system services about it.
18426                    // Note that this is on the same handler as scheduling of broadcasts,
18427                    // which is important because it needs to go first.
18428                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18429                }
18430
18431                if (foreground) {
18432                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18433                            oldUserId));
18434                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18435                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18436                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18437                            oldUserId, userId, uss));
18438                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18439                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18440                }
18441
18442                if (needStart) {
18443                    // Send USER_STARTED broadcast
18444                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18445                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18446                            | Intent.FLAG_RECEIVER_FOREGROUND);
18447                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18448                    broadcastIntentLocked(null, null, intent,
18449                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18450                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18451                }
18452
18453                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18454                    if (userId != UserHandle.USER_OWNER) {
18455                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18456                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18457                        broadcastIntentLocked(null, null, intent, null,
18458                                new IIntentReceiver.Stub() {
18459                                    public void performReceive(Intent intent, int resultCode,
18460                                            String data, Bundle extras, boolean ordered,
18461                                            boolean sticky, int sendingUser) {
18462                                        onUserInitialized(uss, foreground, oldUserId, userId);
18463                                    }
18464                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18465                                true, false, MY_PID, Process.SYSTEM_UID,
18466                                userId);
18467                        uss.initializing = true;
18468                    } else {
18469                        getUserManagerLocked().makeInitialized(userInfo.id);
18470                    }
18471                }
18472
18473                if (foreground) {
18474                    if (!uss.initializing) {
18475                        moveUserToForeground(uss, oldUserId, userId);
18476                    }
18477                } else {
18478                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18479                }
18480
18481                if (needStart) {
18482                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18483                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18484                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18485                    broadcastIntentLocked(null, null, intent,
18486                            null, new IIntentReceiver.Stub() {
18487                                @Override
18488                                public void performReceive(Intent intent, int resultCode, String data,
18489                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18490                                        throws RemoteException {
18491                                }
18492                            }, 0, null, null,
18493                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18494                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18495                }
18496            }
18497        } finally {
18498            Binder.restoreCallingIdentity(ident);
18499        }
18500
18501        return true;
18502    }
18503
18504    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18505        long ident = Binder.clearCallingIdentity();
18506        try {
18507            Intent intent;
18508            if (oldUserId >= 0) {
18509                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18510                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18511                int count = profiles.size();
18512                for (int i = 0; i < count; i++) {
18513                    int profileUserId = profiles.get(i).id;
18514                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18515                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18516                            | Intent.FLAG_RECEIVER_FOREGROUND);
18517                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18518                    broadcastIntentLocked(null, null, intent,
18519                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18520                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18521                }
18522            }
18523            if (newUserId >= 0) {
18524                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18525                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18526                int count = profiles.size();
18527                for (int i = 0; i < count; i++) {
18528                    int profileUserId = profiles.get(i).id;
18529                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18530                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18531                            | Intent.FLAG_RECEIVER_FOREGROUND);
18532                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18533                    broadcastIntentLocked(null, null, intent,
18534                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18535                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18536                }
18537                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18538                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18539                        | Intent.FLAG_RECEIVER_FOREGROUND);
18540                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18541                broadcastIntentLocked(null, null, intent,
18542                        null, null, 0, null, null,
18543                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18544                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18545            }
18546        } finally {
18547            Binder.restoreCallingIdentity(ident);
18548        }
18549    }
18550
18551    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18552            final int newUserId) {
18553        final int N = mUserSwitchObservers.beginBroadcast();
18554        if (N > 0) {
18555            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18556                int mCount = 0;
18557                @Override
18558                public void sendResult(Bundle data) throws RemoteException {
18559                    synchronized (ActivityManagerService.this) {
18560                        if (mCurUserSwitchCallback == this) {
18561                            mCount++;
18562                            if (mCount == N) {
18563                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18564                            }
18565                        }
18566                    }
18567                }
18568            };
18569            synchronized (this) {
18570                uss.switching = true;
18571                mCurUserSwitchCallback = callback;
18572            }
18573            for (int i=0; i<N; i++) {
18574                try {
18575                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18576                            newUserId, callback);
18577                } catch (RemoteException e) {
18578                }
18579            }
18580        } else {
18581            synchronized (this) {
18582                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18583            }
18584        }
18585        mUserSwitchObservers.finishBroadcast();
18586    }
18587
18588    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18589        synchronized (this) {
18590            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18591            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18592        }
18593    }
18594
18595    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18596        mCurUserSwitchCallback = null;
18597        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18598        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18599                oldUserId, newUserId, uss));
18600    }
18601
18602    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18603        synchronized (this) {
18604            if (foreground) {
18605                moveUserToForeground(uss, oldUserId, newUserId);
18606            }
18607        }
18608
18609        completeSwitchAndInitalize(uss, newUserId, true, false);
18610    }
18611
18612    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18613        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18614        if (homeInFront) {
18615            startHomeActivityLocked(newUserId);
18616        } else {
18617            mStackSupervisor.resumeTopActivitiesLocked();
18618        }
18619        EventLogTags.writeAmSwitchUser(newUserId);
18620        getUserManagerLocked().userForeground(newUserId);
18621        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18622    }
18623
18624    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18625        completeSwitchAndInitalize(uss, newUserId, false, true);
18626    }
18627
18628    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18629            boolean clearInitializing, boolean clearSwitching) {
18630        boolean unfrozen = false;
18631        synchronized (this) {
18632            if (clearInitializing) {
18633                uss.initializing = false;
18634                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18635            }
18636            if (clearSwitching) {
18637                uss.switching = false;
18638            }
18639            if (!uss.switching && !uss.initializing) {
18640                mWindowManager.stopFreezingScreen();
18641                unfrozen = true;
18642            }
18643        }
18644        if (unfrozen) {
18645            final int N = mUserSwitchObservers.beginBroadcast();
18646            for (int i=0; i<N; i++) {
18647                try {
18648                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18649                } catch (RemoteException e) {
18650                }
18651            }
18652            mUserSwitchObservers.finishBroadcast();
18653        }
18654    }
18655
18656    void scheduleStartProfilesLocked() {
18657        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18658            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18659                    DateUtils.SECOND_IN_MILLIS);
18660        }
18661    }
18662
18663    void startProfilesLocked() {
18664        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18665        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18666                mCurrentUserId, false /* enabledOnly */);
18667        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18668        for (UserInfo user : profiles) {
18669            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18670                    && user.id != mCurrentUserId) {
18671                toStart.add(user);
18672            }
18673        }
18674        final int n = toStart.size();
18675        int i = 0;
18676        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18677            startUserInBackground(toStart.get(i).id);
18678        }
18679        if (i < n) {
18680            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18681        }
18682    }
18683
18684    void finishUserBoot(UserStartedState uss) {
18685        synchronized (this) {
18686            if (uss.mState == UserStartedState.STATE_BOOTING
18687                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18688                uss.mState = UserStartedState.STATE_RUNNING;
18689                final int userId = uss.mHandle.getIdentifier();
18690                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18691                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18692                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18693                broadcastIntentLocked(null, null, intent,
18694                        null, null, 0, null, null,
18695                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18696                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18697            }
18698        }
18699    }
18700
18701    void finishUserSwitch(UserStartedState uss) {
18702        synchronized (this) {
18703            finishUserBoot(uss);
18704
18705            startProfilesLocked();
18706
18707            int num = mUserLru.size();
18708            int i = 0;
18709            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18710                Integer oldUserId = mUserLru.get(i);
18711                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18712                if (oldUss == null) {
18713                    // Shouldn't happen, but be sane if it does.
18714                    mUserLru.remove(i);
18715                    num--;
18716                    continue;
18717                }
18718                if (oldUss.mState == UserStartedState.STATE_STOPPING
18719                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18720                    // This user is already stopping, doesn't count.
18721                    num--;
18722                    i++;
18723                    continue;
18724                }
18725                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18726                    // Owner and current can't be stopped, but count as running.
18727                    i++;
18728                    continue;
18729                }
18730                // This is a user to be stopped.
18731                stopUserLocked(oldUserId, null);
18732                num--;
18733                i++;
18734            }
18735        }
18736    }
18737
18738    @Override
18739    public int stopUser(final int userId, final IStopUserCallback callback) {
18740        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18741                != PackageManager.PERMISSION_GRANTED) {
18742            String msg = "Permission Denial: switchUser() from pid="
18743                    + Binder.getCallingPid()
18744                    + ", uid=" + Binder.getCallingUid()
18745                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18746            Slog.w(TAG, msg);
18747            throw new SecurityException(msg);
18748        }
18749        if (userId <= 0) {
18750            throw new IllegalArgumentException("Can't stop primary user " + userId);
18751        }
18752        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18753        synchronized (this) {
18754            return stopUserLocked(userId, callback);
18755        }
18756    }
18757
18758    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18759        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18760        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18761            return ActivityManager.USER_OP_IS_CURRENT;
18762        }
18763
18764        final UserStartedState uss = mStartedUsers.get(userId);
18765        if (uss == null) {
18766            // User is not started, nothing to do...  but we do need to
18767            // callback if requested.
18768            if (callback != null) {
18769                mHandler.post(new Runnable() {
18770                    @Override
18771                    public void run() {
18772                        try {
18773                            callback.userStopped(userId);
18774                        } catch (RemoteException e) {
18775                        }
18776                    }
18777                });
18778            }
18779            return ActivityManager.USER_OP_SUCCESS;
18780        }
18781
18782        if (callback != null) {
18783            uss.mStopCallbacks.add(callback);
18784        }
18785
18786        if (uss.mState != UserStartedState.STATE_STOPPING
18787                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18788            uss.mState = UserStartedState.STATE_STOPPING;
18789            updateStartedUserArrayLocked();
18790
18791            long ident = Binder.clearCallingIdentity();
18792            try {
18793                // We are going to broadcast ACTION_USER_STOPPING and then
18794                // once that is done send a final ACTION_SHUTDOWN and then
18795                // stop the user.
18796                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18797                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18798                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18799                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18800                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18801                // This is the result receiver for the final shutdown broadcast.
18802                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18803                    @Override
18804                    public void performReceive(Intent intent, int resultCode, String data,
18805                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18806                        finishUserStop(uss);
18807                    }
18808                };
18809                // This is the result receiver for the initial stopping broadcast.
18810                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18811                    @Override
18812                    public void performReceive(Intent intent, int resultCode, String data,
18813                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18814                        // On to the next.
18815                        synchronized (ActivityManagerService.this) {
18816                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18817                                // Whoops, we are being started back up.  Abort, abort!
18818                                return;
18819                            }
18820                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18821                        }
18822                        mBatteryStatsService.noteEvent(
18823                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18824                                Integer.toString(userId), userId);
18825                        mSystemServiceManager.stopUser(userId);
18826                        broadcastIntentLocked(null, null, shutdownIntent,
18827                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18828                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18829                    }
18830                };
18831                // Kick things off.
18832                broadcastIntentLocked(null, null, stoppingIntent,
18833                        null, stoppingReceiver, 0, null, null,
18834                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18835                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18836            } finally {
18837                Binder.restoreCallingIdentity(ident);
18838            }
18839        }
18840
18841        return ActivityManager.USER_OP_SUCCESS;
18842    }
18843
18844    void finishUserStop(UserStartedState uss) {
18845        final int userId = uss.mHandle.getIdentifier();
18846        boolean stopped;
18847        ArrayList<IStopUserCallback> callbacks;
18848        synchronized (this) {
18849            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18850            if (mStartedUsers.get(userId) != uss) {
18851                stopped = false;
18852            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18853                stopped = false;
18854            } else {
18855                stopped = true;
18856                // User can no longer run.
18857                mStartedUsers.remove(userId);
18858                mUserLru.remove(Integer.valueOf(userId));
18859                updateStartedUserArrayLocked();
18860
18861                // Clean up all state and processes associated with the user.
18862                // Kill all the processes for the user.
18863                forceStopUserLocked(userId, "finish user");
18864            }
18865
18866            // Explicitly remove the old information in mRecentTasks.
18867            removeRecentTasksForUserLocked(userId);
18868        }
18869
18870        for (int i=0; i<callbacks.size(); i++) {
18871            try {
18872                if (stopped) callbacks.get(i).userStopped(userId);
18873                else callbacks.get(i).userStopAborted(userId);
18874            } catch (RemoteException e) {
18875            }
18876        }
18877
18878        if (stopped) {
18879            mSystemServiceManager.cleanupUser(userId);
18880            synchronized (this) {
18881                mStackSupervisor.removeUserLocked(userId);
18882            }
18883        }
18884    }
18885
18886    @Override
18887    public UserInfo getCurrentUser() {
18888        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18889                != PackageManager.PERMISSION_GRANTED) && (
18890                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18891                != PackageManager.PERMISSION_GRANTED)) {
18892            String msg = "Permission Denial: getCurrentUser() from pid="
18893                    + Binder.getCallingPid()
18894                    + ", uid=" + Binder.getCallingUid()
18895                    + " requires " + INTERACT_ACROSS_USERS;
18896            Slog.w(TAG, msg);
18897            throw new SecurityException(msg);
18898        }
18899        synchronized (this) {
18900            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18901            return getUserManagerLocked().getUserInfo(userId);
18902        }
18903    }
18904
18905    int getCurrentUserIdLocked() {
18906        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18907    }
18908
18909    @Override
18910    public boolean isUserRunning(int userId, boolean orStopped) {
18911        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18912                != PackageManager.PERMISSION_GRANTED) {
18913            String msg = "Permission Denial: isUserRunning() from pid="
18914                    + Binder.getCallingPid()
18915                    + ", uid=" + Binder.getCallingUid()
18916                    + " requires " + INTERACT_ACROSS_USERS;
18917            Slog.w(TAG, msg);
18918            throw new SecurityException(msg);
18919        }
18920        synchronized (this) {
18921            return isUserRunningLocked(userId, orStopped);
18922        }
18923    }
18924
18925    boolean isUserRunningLocked(int userId, boolean orStopped) {
18926        UserStartedState state = mStartedUsers.get(userId);
18927        if (state == null) {
18928            return false;
18929        }
18930        if (orStopped) {
18931            return true;
18932        }
18933        return state.mState != UserStartedState.STATE_STOPPING
18934                && state.mState != UserStartedState.STATE_SHUTDOWN;
18935    }
18936
18937    @Override
18938    public int[] getRunningUserIds() {
18939        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18940                != PackageManager.PERMISSION_GRANTED) {
18941            String msg = "Permission Denial: isUserRunning() from pid="
18942                    + Binder.getCallingPid()
18943                    + ", uid=" + Binder.getCallingUid()
18944                    + " requires " + INTERACT_ACROSS_USERS;
18945            Slog.w(TAG, msg);
18946            throw new SecurityException(msg);
18947        }
18948        synchronized (this) {
18949            return mStartedUserArray;
18950        }
18951    }
18952
18953    private void updateStartedUserArrayLocked() {
18954        int num = 0;
18955        for (int i=0; i<mStartedUsers.size();  i++) {
18956            UserStartedState uss = mStartedUsers.valueAt(i);
18957            // This list does not include stopping users.
18958            if (uss.mState != UserStartedState.STATE_STOPPING
18959                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18960                num++;
18961            }
18962        }
18963        mStartedUserArray = new int[num];
18964        num = 0;
18965        for (int i=0; i<mStartedUsers.size();  i++) {
18966            UserStartedState uss = mStartedUsers.valueAt(i);
18967            if (uss.mState != UserStartedState.STATE_STOPPING
18968                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18969                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18970                num++;
18971            }
18972        }
18973    }
18974
18975    @Override
18976    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18977        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18978                != PackageManager.PERMISSION_GRANTED) {
18979            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18980                    + Binder.getCallingPid()
18981                    + ", uid=" + Binder.getCallingUid()
18982                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18983            Slog.w(TAG, msg);
18984            throw new SecurityException(msg);
18985        }
18986
18987        mUserSwitchObservers.register(observer);
18988    }
18989
18990    @Override
18991    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18992        mUserSwitchObservers.unregister(observer);
18993    }
18994
18995    private boolean userExists(int userId) {
18996        if (userId == 0) {
18997            return true;
18998        }
18999        UserManagerService ums = getUserManagerLocked();
19000        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19001    }
19002
19003    int[] getUsersLocked() {
19004        UserManagerService ums = getUserManagerLocked();
19005        return ums != null ? ums.getUserIds() : new int[] { 0 };
19006    }
19007
19008    UserManagerService getUserManagerLocked() {
19009        if (mUserManager == null) {
19010            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19011            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19012        }
19013        return mUserManager;
19014    }
19015
19016    private int applyUserId(int uid, int userId) {
19017        return UserHandle.getUid(userId, uid);
19018    }
19019
19020    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19021        if (info == null) return null;
19022        ApplicationInfo newInfo = new ApplicationInfo(info);
19023        newInfo.uid = applyUserId(info.uid, userId);
19024        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19025                + info.packageName;
19026        return newInfo;
19027    }
19028
19029    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19030        if (aInfo == null
19031                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19032            return aInfo;
19033        }
19034
19035        ActivityInfo info = new ActivityInfo(aInfo);
19036        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19037        return info;
19038    }
19039
19040    private final class LocalService extends ActivityManagerInternal {
19041        @Override
19042        public void goingToSleep() {
19043            ActivityManagerService.this.goingToSleep();
19044        }
19045
19046        @Override
19047        public void wakingUp() {
19048            ActivityManagerService.this.wakingUp();
19049        }
19050
19051        @Override
19052        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19053                String processName, String abiOverride, int uid, Runnable crashHandler) {
19054            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19055                    processName, abiOverride, uid, crashHandler);
19056        }
19057    }
19058
19059    /**
19060     * An implementation of IAppTask, that allows an app to manage its own tasks via
19061     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19062     * only the process that calls getAppTasks() can call the AppTask methods.
19063     */
19064    class AppTaskImpl extends IAppTask.Stub {
19065        private int mTaskId;
19066        private int mCallingUid;
19067
19068        public AppTaskImpl(int taskId, int callingUid) {
19069            mTaskId = taskId;
19070            mCallingUid = callingUid;
19071        }
19072
19073        private void checkCaller() {
19074            if (mCallingUid != Binder.getCallingUid()) {
19075                throw new SecurityException("Caller " + mCallingUid
19076                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19077            }
19078        }
19079
19080        @Override
19081        public void finishAndRemoveTask() {
19082            checkCaller();
19083
19084            synchronized (ActivityManagerService.this) {
19085                long origId = Binder.clearCallingIdentity();
19086                try {
19087                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19088                    if (tr == null) {
19089                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19090                    }
19091                    // Only kill the process if we are not a new document
19092                    int flags = tr.getBaseIntent().getFlags();
19093                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19094                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19095                    removeTaskByIdLocked(mTaskId,
19096                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19097                } finally {
19098                    Binder.restoreCallingIdentity(origId);
19099                }
19100            }
19101        }
19102
19103        @Override
19104        public ActivityManager.RecentTaskInfo getTaskInfo() {
19105            checkCaller();
19106
19107            synchronized (ActivityManagerService.this) {
19108                long origId = Binder.clearCallingIdentity();
19109                try {
19110                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19111                    if (tr == null) {
19112                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19113                    }
19114                    return createRecentTaskInfoFromTaskRecord(tr);
19115                } finally {
19116                    Binder.restoreCallingIdentity(origId);
19117                }
19118            }
19119        }
19120
19121        @Override
19122        public void moveToFront() {
19123            checkCaller();
19124
19125            final TaskRecord tr;
19126            synchronized (ActivityManagerService.this) {
19127                tr = recentTaskForIdLocked(mTaskId);
19128                if (tr == null) {
19129                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19130                }
19131                if (tr.getRootActivity() != null) {
19132                    moveTaskToFrontLocked(tr.taskId, 0, null);
19133                    return;
19134                }
19135            }
19136
19137            startActivityFromRecentsInner(tr.taskId, null);
19138        }
19139
19140        @Override
19141        public int startActivity(IBinder whoThread, String callingPackage,
19142                Intent intent, String resolvedType, Bundle options) {
19143            checkCaller();
19144
19145            int callingUser = UserHandle.getCallingUserId();
19146            TaskRecord tr;
19147            IApplicationThread appThread;
19148            synchronized (ActivityManagerService.this) {
19149                tr = recentTaskForIdLocked(mTaskId);
19150                if (tr == null) {
19151                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19152                }
19153                appThread = ApplicationThreadNative.asInterface(whoThread);
19154                if (appThread == null) {
19155                    throw new IllegalArgumentException("Bad app thread " + appThread);
19156                }
19157            }
19158            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19159                    resolvedType, null, null, null, null, 0, 0, null, null,
19160                    null, options, callingUser, null, tr);
19161        }
19162
19163        @Override
19164        public void setExcludeFromRecents(boolean exclude) {
19165            checkCaller();
19166
19167            synchronized (ActivityManagerService.this) {
19168                long origId = Binder.clearCallingIdentity();
19169                try {
19170                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19171                    if (tr == null) {
19172                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19173                    }
19174                    Intent intent = tr.getBaseIntent();
19175                    if (exclude) {
19176                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19177                    } else {
19178                        intent.setFlags(intent.getFlags()
19179                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19180                    }
19181                } finally {
19182                    Binder.restoreCallingIdentity(origId);
19183                }
19184            }
19185        }
19186    }
19187}
19188