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_BUFFERS]).append(" kB buffers, ");
1738                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1739                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1740                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1741                            logBuilder.append("  ZRAM: ");
1742                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1743                            logBuilder.append(" kB RAM, ");
1744                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1745                            logBuilder.append(" kB swap total, ");
1746                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1747                            logBuilder.append(" kB swap free\n");
1748                        }
1749                        Slog.i(TAG, logBuilder.toString());
1750
1751                        StringBuilder dropBuilder = new StringBuilder(1024);
1752                        /*
1753                        StringWriter oomSw = new StringWriter();
1754                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1755                        StringWriter catSw = new StringWriter();
1756                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1757                        String[] emptyArgs = new String[] { };
1758                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1759                        oomPw.flush();
1760                        String oomString = oomSw.toString();
1761                        */
1762                        dropBuilder.append(stack);
1763                        dropBuilder.append('\n');
1764                        dropBuilder.append('\n');
1765                        dropBuilder.append(logBuilder);
1766                        dropBuilder.append('\n');
1767                        /*
1768                        dropBuilder.append(oomString);
1769                        dropBuilder.append('\n');
1770                        */
1771                        StringWriter catSw = new StringWriter();
1772                        synchronized (ActivityManagerService.this) {
1773                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1774                            String[] emptyArgs = new String[] { };
1775                            catPw.println();
1776                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1777                            catPw.println();
1778                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1779                                    false, false, null);
1780                            catPw.println();
1781                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1782                            catPw.flush();
1783                        }
1784                        dropBuilder.append(catSw.toString());
1785                        addErrorToDropBox("lowmem", null, "system_server", null,
1786                                null, tag.toString(), dropBuilder.toString(), null, null);
1787                        //Slog.i(TAG, "Sent to dropbox:");
1788                        //Slog.i(TAG, dropBuilder.toString());
1789                        synchronized (ActivityManagerService.this) {
1790                            long now = SystemClock.uptimeMillis();
1791                            if (mLastMemUsageReportTime < now) {
1792                                mLastMemUsageReportTime = now;
1793                            }
1794                        }
1795                    }
1796                };
1797                thread.start();
1798                break;
1799            }
1800            case START_USER_SWITCH_MSG: {
1801                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1802                break;
1803            }
1804            case REPORT_USER_SWITCH_MSG: {
1805                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1806                break;
1807            }
1808            case CONTINUE_USER_SWITCH_MSG: {
1809                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1810                break;
1811            }
1812            case USER_SWITCH_TIMEOUT_MSG: {
1813                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1814                break;
1815            }
1816            case IMMERSIVE_MODE_LOCK_MSG: {
1817                final boolean nextState = (msg.arg1 != 0);
1818                if (mUpdateLock.isHeld() != nextState) {
1819                    if (DEBUG_IMMERSIVE) {
1820                        final ActivityRecord r = (ActivityRecord) msg.obj;
1821                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1822                    }
1823                    if (nextState) {
1824                        mUpdateLock.acquire();
1825                    } else {
1826                        mUpdateLock.release();
1827                    }
1828                }
1829                break;
1830            }
1831            case PERSIST_URI_GRANTS_MSG: {
1832                writeGrantedUriPermissions();
1833                break;
1834            }
1835            case REQUEST_ALL_PSS_MSG: {
1836                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1837                break;
1838            }
1839            case START_PROFILES_MSG: {
1840                synchronized (ActivityManagerService.this) {
1841                    startProfilesLocked();
1842                }
1843                break;
1844            }
1845            case UPDATE_TIME: {
1846                synchronized (ActivityManagerService.this) {
1847                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1848                        ProcessRecord r = mLruProcesses.get(i);
1849                        if (r.thread != null) {
1850                            try {
1851                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1852                            } catch (RemoteException ex) {
1853                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1854                            }
1855                        }
1856                    }
1857                }
1858                break;
1859            }
1860            case SYSTEM_USER_START_MSG: {
1861                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1862                        Integer.toString(msg.arg1), msg.arg1);
1863                mSystemServiceManager.startUser(msg.arg1);
1864                break;
1865            }
1866            case SYSTEM_USER_CURRENT_MSG: {
1867                mBatteryStatsService.noteEvent(
1868                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1869                        Integer.toString(msg.arg2), msg.arg2);
1870                mBatteryStatsService.noteEvent(
1871                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1872                        Integer.toString(msg.arg1), msg.arg1);
1873                mSystemServiceManager.switchUser(msg.arg1);
1874                mLockToAppRequest.clearPrompt();
1875                break;
1876            }
1877            case ENTER_ANIMATION_COMPLETE_MSG: {
1878                synchronized (ActivityManagerService.this) {
1879                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1880                    if (r != null && r.app != null && r.app.thread != null) {
1881                        try {
1882                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1883                        } catch (RemoteException e) {
1884                        }
1885                    }
1886                }
1887                break;
1888            }
1889            case FINISH_BOOTING_MSG: {
1890                if (msg.arg1 != 0) {
1891                    finishBooting();
1892                }
1893                if (msg.arg2 != 0) {
1894                    enableScreenAfterBoot();
1895                }
1896                break;
1897            }
1898            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1899                try {
1900                    Locale l = (Locale) msg.obj;
1901                    IBinder service = ServiceManager.getService("mount");
1902                    IMountService mountService = IMountService.Stub.asInterface(service);
1903                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1904                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1905                } catch (RemoteException e) {
1906                    Log.e(TAG, "Error storing locale for decryption UI", e);
1907                }
1908                break;
1909            }
1910            }
1911        }
1912    };
1913
1914    static final int COLLECT_PSS_BG_MSG = 1;
1915
1916    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1917        @Override
1918        public void handleMessage(Message msg) {
1919            switch (msg.what) {
1920            case COLLECT_PSS_BG_MSG: {
1921                long start = SystemClock.uptimeMillis();
1922                MemInfoReader memInfo = null;
1923                synchronized (ActivityManagerService.this) {
1924                    if (mFullPssPending) {
1925                        mFullPssPending = false;
1926                        memInfo = new MemInfoReader();
1927                    }
1928                }
1929                if (memInfo != null) {
1930                    updateCpuStatsNow();
1931                    long nativeTotalPss = 0;
1932                    synchronized (mProcessCpuTracker) {
1933                        final int N = mProcessCpuTracker.countStats();
1934                        for (int j=0; j<N; j++) {
1935                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1936                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1937                                // This is definitely an application process; skip it.
1938                                continue;
1939                            }
1940                            synchronized (mPidsSelfLocked) {
1941                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1942                                    // This is one of our own processes; skip it.
1943                                    continue;
1944                                }
1945                            }
1946                            nativeTotalPss += Debug.getPss(st.pid, null);
1947                        }
1948                    }
1949                    memInfo.readMemInfo();
1950                    synchronized (ActivityManagerService.this) {
1951                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1952                                + (SystemClock.uptimeMillis()-start) + "ms");
1953                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1954                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1955                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1956                                        +memInfo.getSlabSizeKb(),
1957                                nativeTotalPss);
1958                    }
1959                }
1960
1961                int i=0, num=0;
1962                long[] tmp = new long[1];
1963                do {
1964                    ProcessRecord proc;
1965                    int procState;
1966                    int pid;
1967                    synchronized (ActivityManagerService.this) {
1968                        if (i >= mPendingPssProcesses.size()) {
1969                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1970                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1971                            mPendingPssProcesses.clear();
1972                            return;
1973                        }
1974                        proc = mPendingPssProcesses.get(i);
1975                        procState = proc.pssProcState;
1976                        if (proc.thread != null && procState == proc.setProcState) {
1977                            pid = proc.pid;
1978                        } else {
1979                            proc = null;
1980                            pid = 0;
1981                        }
1982                        i++;
1983                    }
1984                    if (proc != null) {
1985                        long pss = Debug.getPss(pid, tmp);
1986                        synchronized (ActivityManagerService.this) {
1987                            if (proc.thread != null && proc.setProcState == procState
1988                                    && proc.pid == pid) {
1989                                num++;
1990                                proc.lastPssTime = SystemClock.uptimeMillis();
1991                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1992                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1993                                        + ": " + pss + " lastPss=" + proc.lastPss
1994                                        + " state=" + ProcessList.makeProcStateString(procState));
1995                                if (proc.initialIdlePss == 0) {
1996                                    proc.initialIdlePss = pss;
1997                                }
1998                                proc.lastPss = pss;
1999                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2000                                    proc.lastCachedPss = pss;
2001                                }
2002                            }
2003                        }
2004                    }
2005                } while (true);
2006            }
2007            }
2008        }
2009    };
2010
2011    /**
2012     * Monitor for package changes and update our internal state.
2013     */
2014    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2015        @Override
2016        public void onPackageRemoved(String packageName, int uid) {
2017            // Remove all tasks with activities in the specified package from the list of recent tasks
2018            final int eventUserId = getChangingUserId();
2019            synchronized (ActivityManagerService.this) {
2020                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2021                    TaskRecord tr = mRecentTasks.get(i);
2022                    if (tr.userId != eventUserId) continue;
2023
2024                    ComponentName cn = tr.intent.getComponent();
2025                    if (cn != null && cn.getPackageName().equals(packageName)) {
2026                        // If the package name matches, remove the task and kill the process
2027                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2028                    }
2029                }
2030            }
2031        }
2032
2033        @Override
2034        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2035            onPackageModified(packageName);
2036            return true;
2037        }
2038
2039        @Override
2040        public void onPackageModified(String packageName) {
2041            final int eventUserId = getChangingUserId();
2042            final IPackageManager pm = AppGlobals.getPackageManager();
2043            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2044                    new ArrayList<Pair<Intent, Integer>>();
2045            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2046            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2047            // Copy the list of recent tasks so that we don't hold onto the lock on
2048            // ActivityManagerService for long periods while checking if components exist.
2049            synchronized (ActivityManagerService.this) {
2050                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2051                    TaskRecord tr = mRecentTasks.get(i);
2052                    if (tr.userId != eventUserId) continue;
2053
2054                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2055                }
2056            }
2057            // Check the recent tasks and filter out all tasks with components that no longer exist.
2058            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2059                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2060                ComponentName cn = p.first.getComponent();
2061                if (cn != null && cn.getPackageName().equals(packageName)) {
2062                    if (componentsKnownToExist.contains(cn)) {
2063                        // If we know that the component still exists in the package, then skip
2064                        continue;
2065                    }
2066                    try {
2067                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2068                        if (info != null) {
2069                            componentsKnownToExist.add(cn);
2070                        } else {
2071                            tasksToRemove.add(p.second);
2072                        }
2073                    } catch (RemoteException e) {
2074                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2075                    }
2076                }
2077            }
2078            // Prune all the tasks with removed components from the list of recent tasks
2079            synchronized (ActivityManagerService.this) {
2080                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2081                    // Remove the task but don't kill the process (since other components in that
2082                    // package may still be running and in the background)
2083                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2084                }
2085            }
2086        }
2087
2088        @Override
2089        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2090            // Force stop the specified packages
2091            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2092            if (packages != null) {
2093                for (String pkg : packages) {
2094                    synchronized (ActivityManagerService.this) {
2095                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2096                                userId, "finished booting")) {
2097                            return true;
2098                        }
2099                    }
2100                }
2101            }
2102            return false;
2103        }
2104    };
2105
2106    public void setSystemProcess() {
2107        try {
2108            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2109            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2110            ServiceManager.addService("meminfo", new MemBinder(this));
2111            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2112            ServiceManager.addService("dbinfo", new DbBinder(this));
2113            if (MONITOR_CPU_USAGE) {
2114                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2115            }
2116            ServiceManager.addService("permission", new PermissionController(this));
2117
2118            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2119                    "android", STOCK_PM_FLAGS);
2120            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2121
2122            synchronized (this) {
2123                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2124                app.persistent = true;
2125                app.pid = MY_PID;
2126                app.maxAdj = ProcessList.SYSTEM_ADJ;
2127                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2128                mProcessNames.put(app.processName, app.uid, app);
2129                synchronized (mPidsSelfLocked) {
2130                    mPidsSelfLocked.put(app.pid, app);
2131                }
2132                updateLruProcessLocked(app, false, null);
2133                updateOomAdjLocked();
2134            }
2135        } catch (PackageManager.NameNotFoundException e) {
2136            throw new RuntimeException(
2137                    "Unable to find android system package", e);
2138        }
2139    }
2140
2141    public void setWindowManager(WindowManagerService wm) {
2142        mWindowManager = wm;
2143        mStackSupervisor.setWindowManager(wm);
2144    }
2145
2146    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2147        mUsageStatsService = usageStatsManager;
2148    }
2149
2150    public void startObservingNativeCrashes() {
2151        final NativeCrashListener ncl = new NativeCrashListener(this);
2152        ncl.start();
2153    }
2154
2155    public IAppOpsService getAppOpsService() {
2156        return mAppOpsService;
2157    }
2158
2159    static class MemBinder extends Binder {
2160        ActivityManagerService mActivityManagerService;
2161        MemBinder(ActivityManagerService activityManagerService) {
2162            mActivityManagerService = activityManagerService;
2163        }
2164
2165        @Override
2166        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2167            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2168                    != PackageManager.PERMISSION_GRANTED) {
2169                pw.println("Permission Denial: can't dump meminfo from from pid="
2170                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2171                        + " without permission " + android.Manifest.permission.DUMP);
2172                return;
2173            }
2174
2175            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2176        }
2177    }
2178
2179    static class GraphicsBinder extends Binder {
2180        ActivityManagerService mActivityManagerService;
2181        GraphicsBinder(ActivityManagerService activityManagerService) {
2182            mActivityManagerService = activityManagerService;
2183        }
2184
2185        @Override
2186        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2187            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2188                    != PackageManager.PERMISSION_GRANTED) {
2189                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2190                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2191                        + " without permission " + android.Manifest.permission.DUMP);
2192                return;
2193            }
2194
2195            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2196        }
2197    }
2198
2199    static class DbBinder extends Binder {
2200        ActivityManagerService mActivityManagerService;
2201        DbBinder(ActivityManagerService activityManagerService) {
2202            mActivityManagerService = activityManagerService;
2203        }
2204
2205        @Override
2206        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2207            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2208                    != PackageManager.PERMISSION_GRANTED) {
2209                pw.println("Permission Denial: can't dump dbinfo from from pid="
2210                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2211                        + " without permission " + android.Manifest.permission.DUMP);
2212                return;
2213            }
2214
2215            mActivityManagerService.dumpDbInfo(fd, pw, args);
2216        }
2217    }
2218
2219    static class CpuBinder extends Binder {
2220        ActivityManagerService mActivityManagerService;
2221        CpuBinder(ActivityManagerService activityManagerService) {
2222            mActivityManagerService = activityManagerService;
2223        }
2224
2225        @Override
2226        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2227            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2228                    != PackageManager.PERMISSION_GRANTED) {
2229                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2230                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2231                        + " without permission " + android.Manifest.permission.DUMP);
2232                return;
2233            }
2234
2235            synchronized (mActivityManagerService.mProcessCpuTracker) {
2236                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2237                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2238                        SystemClock.uptimeMillis()));
2239            }
2240        }
2241    }
2242
2243    public static final class Lifecycle extends SystemService {
2244        private final ActivityManagerService mService;
2245
2246        public Lifecycle(Context context) {
2247            super(context);
2248            mService = new ActivityManagerService(context);
2249        }
2250
2251        @Override
2252        public void onStart() {
2253            mService.start();
2254        }
2255
2256        public ActivityManagerService getService() {
2257            return mService;
2258        }
2259    }
2260
2261    // Note: This method is invoked on the main thread but may need to attach various
2262    // handlers to other threads.  So take care to be explicit about the looper.
2263    public ActivityManagerService(Context systemContext) {
2264        mContext = systemContext;
2265        mFactoryTest = FactoryTest.getMode();
2266        mSystemThread = ActivityThread.currentActivityThread();
2267
2268        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2269
2270        mHandlerThread = new ServiceThread(TAG,
2271                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2272        mHandlerThread.start();
2273        mHandler = new MainHandler(mHandlerThread.getLooper());
2274
2275        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2276                "foreground", BROADCAST_FG_TIMEOUT, false);
2277        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278                "background", BROADCAST_BG_TIMEOUT, true);
2279        mBroadcastQueues[0] = mFgBroadcastQueue;
2280        mBroadcastQueues[1] = mBgBroadcastQueue;
2281
2282        mServices = new ActiveServices(this);
2283        mProviderMap = new ProviderMap(this);
2284
2285        // TODO: Move creation of battery stats service outside of activity manager service.
2286        File dataDir = Environment.getDataDirectory();
2287        File systemDir = new File(dataDir, "system");
2288        systemDir.mkdirs();
2289        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2290        mBatteryStatsService.getActiveStatistics().readLocked();
2291        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2292        mOnBattery = DEBUG_POWER ? true
2293                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2294        mBatteryStatsService.getActiveStatistics().setCallback(this);
2295
2296        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2297
2298        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2299
2300        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2301
2302        // User 0 is the first and only user that runs at boot.
2303        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2304        mUserLru.add(Integer.valueOf(0));
2305        updateStartedUserArrayLocked();
2306
2307        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2308            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2309
2310        mConfiguration.setToDefaults();
2311        mConfiguration.setLocale(Locale.getDefault());
2312
2313        mConfigurationSeq = mConfiguration.seq = 1;
2314        mProcessCpuTracker.init();
2315
2316        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2317        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2318        mStackSupervisor = new ActivityStackSupervisor(this);
2319        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2320
2321        mProcessCpuThread = new Thread("CpuTracker") {
2322            @Override
2323            public void run() {
2324                while (true) {
2325                    try {
2326                        try {
2327                            synchronized(this) {
2328                                final long now = SystemClock.uptimeMillis();
2329                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2330                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2331                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2332                                //        + ", write delay=" + nextWriteDelay);
2333                                if (nextWriteDelay < nextCpuDelay) {
2334                                    nextCpuDelay = nextWriteDelay;
2335                                }
2336                                if (nextCpuDelay > 0) {
2337                                    mProcessCpuMutexFree.set(true);
2338                                    this.wait(nextCpuDelay);
2339                                }
2340                            }
2341                        } catch (InterruptedException e) {
2342                        }
2343                        updateCpuStatsNow();
2344                    } catch (Exception e) {
2345                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2346                    }
2347                }
2348            }
2349        };
2350
2351        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2352
2353        Watchdog.getInstance().addMonitor(this);
2354        Watchdog.getInstance().addThread(mHandler);
2355    }
2356
2357    public void setSystemServiceManager(SystemServiceManager mgr) {
2358        mSystemServiceManager = mgr;
2359    }
2360
2361    private void start() {
2362        Process.removeAllProcessGroups();
2363        mProcessCpuThread.start();
2364
2365        mBatteryStatsService.publish(mContext);
2366        mAppOpsService.publish(mContext);
2367        Slog.d("AppOps", "AppOpsService published");
2368        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2369    }
2370
2371    public void initPowerManagement() {
2372        mStackSupervisor.initPowerManagement();
2373        mBatteryStatsService.initPowerManagement();
2374    }
2375
2376    @Override
2377    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2378            throws RemoteException {
2379        if (code == SYSPROPS_TRANSACTION) {
2380            // We need to tell all apps about the system property change.
2381            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2382            synchronized(this) {
2383                final int NP = mProcessNames.getMap().size();
2384                for (int ip=0; ip<NP; ip++) {
2385                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2386                    final int NA = apps.size();
2387                    for (int ia=0; ia<NA; ia++) {
2388                        ProcessRecord app = apps.valueAt(ia);
2389                        if (app.thread != null) {
2390                            procs.add(app.thread.asBinder());
2391                        }
2392                    }
2393                }
2394            }
2395
2396            int N = procs.size();
2397            for (int i=0; i<N; i++) {
2398                Parcel data2 = Parcel.obtain();
2399                try {
2400                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2401                } catch (RemoteException e) {
2402                }
2403                data2.recycle();
2404            }
2405        }
2406        try {
2407            return super.onTransact(code, data, reply, flags);
2408        } catch (RuntimeException e) {
2409            // The activity manager only throws security exceptions, so let's
2410            // log all others.
2411            if (!(e instanceof SecurityException)) {
2412                Slog.wtf(TAG, "Activity Manager Crash", e);
2413            }
2414            throw e;
2415        }
2416    }
2417
2418    void updateCpuStats() {
2419        final long now = SystemClock.uptimeMillis();
2420        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2421            return;
2422        }
2423        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2424            synchronized (mProcessCpuThread) {
2425                mProcessCpuThread.notify();
2426            }
2427        }
2428    }
2429
2430    void updateCpuStatsNow() {
2431        synchronized (mProcessCpuTracker) {
2432            mProcessCpuMutexFree.set(false);
2433            final long now = SystemClock.uptimeMillis();
2434            boolean haveNewCpuStats = false;
2435
2436            if (MONITOR_CPU_USAGE &&
2437                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2438                mLastCpuTime.set(now);
2439                haveNewCpuStats = true;
2440                mProcessCpuTracker.update();
2441                //Slog.i(TAG, mProcessCpu.printCurrentState());
2442                //Slog.i(TAG, "Total CPU usage: "
2443                //        + mProcessCpu.getTotalCpuPercent() + "%");
2444
2445                // Slog the cpu usage if the property is set.
2446                if ("true".equals(SystemProperties.get("events.cpu"))) {
2447                    int user = mProcessCpuTracker.getLastUserTime();
2448                    int system = mProcessCpuTracker.getLastSystemTime();
2449                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2450                    int irq = mProcessCpuTracker.getLastIrqTime();
2451                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2452                    int idle = mProcessCpuTracker.getLastIdleTime();
2453
2454                    int total = user + system + iowait + irq + softIrq + idle;
2455                    if (total == 0) total = 1;
2456
2457                    EventLog.writeEvent(EventLogTags.CPU,
2458                            ((user+system+iowait+irq+softIrq) * 100) / total,
2459                            (user * 100) / total,
2460                            (system * 100) / total,
2461                            (iowait * 100) / total,
2462                            (irq * 100) / total,
2463                            (softIrq * 100) / total);
2464                }
2465            }
2466
2467            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2468            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2469            synchronized(bstats) {
2470                synchronized(mPidsSelfLocked) {
2471                    if (haveNewCpuStats) {
2472                        if (mOnBattery) {
2473                            int perc = bstats.startAddingCpuLocked();
2474                            int totalUTime = 0;
2475                            int totalSTime = 0;
2476                            final int N = mProcessCpuTracker.countStats();
2477                            for (int i=0; i<N; i++) {
2478                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2479                                if (!st.working) {
2480                                    continue;
2481                                }
2482                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2483                                int otherUTime = (st.rel_utime*perc)/100;
2484                                int otherSTime = (st.rel_stime*perc)/100;
2485                                totalUTime += otherUTime;
2486                                totalSTime += otherSTime;
2487                                if (pr != null) {
2488                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2489                                    if (ps == null || !ps.isActive()) {
2490                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2491                                                pr.info.uid, pr.processName);
2492                                    }
2493                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2494                                            st.rel_stime-otherSTime);
2495                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2496                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2497                                } else {
2498                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2499                                    if (ps == null || !ps.isActive()) {
2500                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2501                                                bstats.mapUid(st.uid), st.name);
2502                                    }
2503                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2504                                            st.rel_stime-otherSTime);
2505                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2506                                }
2507                            }
2508                            bstats.finishAddingCpuLocked(perc, totalUTime,
2509                                    totalSTime, cpuSpeedTimes);
2510                        }
2511                    }
2512                }
2513
2514                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2515                    mLastWriteTime = now;
2516                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2517                }
2518            }
2519        }
2520    }
2521
2522    @Override
2523    public void batteryNeedsCpuUpdate() {
2524        updateCpuStatsNow();
2525    }
2526
2527    @Override
2528    public void batteryPowerChanged(boolean onBattery) {
2529        // When plugging in, update the CPU stats first before changing
2530        // the plug state.
2531        updateCpuStatsNow();
2532        synchronized (this) {
2533            synchronized(mPidsSelfLocked) {
2534                mOnBattery = DEBUG_POWER ? true : onBattery;
2535            }
2536        }
2537    }
2538
2539    /**
2540     * Initialize the application bind args. These are passed to each
2541     * process when the bindApplication() IPC is sent to the process. They're
2542     * lazily setup to make sure the services are running when they're asked for.
2543     */
2544    private HashMap<String, IBinder> getCommonServicesLocked() {
2545        if (mAppBindArgs == null) {
2546            mAppBindArgs = new HashMap<String, IBinder>();
2547
2548            // Setup the application init args
2549            mAppBindArgs.put("package", ServiceManager.getService("package"));
2550            mAppBindArgs.put("window", ServiceManager.getService("window"));
2551            mAppBindArgs.put(Context.ALARM_SERVICE,
2552                    ServiceManager.getService(Context.ALARM_SERVICE));
2553        }
2554        return mAppBindArgs;
2555    }
2556
2557    final void setFocusedActivityLocked(ActivityRecord r) {
2558        if (mFocusedActivity != r) {
2559            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2560            mFocusedActivity = r;
2561            if (r.task != null && r.task.voiceInteractor != null) {
2562                startRunningVoiceLocked();
2563            } else {
2564                finishRunningVoiceLocked();
2565            }
2566            mStackSupervisor.setFocusedStack(r);
2567            if (r != null) {
2568                mWindowManager.setFocusedApp(r.appToken, true);
2569            }
2570            applyUpdateLockStateLocked(r);
2571        }
2572    }
2573
2574    final void clearFocusedActivity(ActivityRecord r) {
2575        if (mFocusedActivity == r) {
2576            mFocusedActivity = null;
2577        }
2578    }
2579
2580    @Override
2581    public void setFocusedStack(int stackId) {
2582        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2583        synchronized (ActivityManagerService.this) {
2584            ActivityStack stack = mStackSupervisor.getStack(stackId);
2585            if (stack != null) {
2586                ActivityRecord r = stack.topRunningActivityLocked(null);
2587                if (r != null) {
2588                    setFocusedActivityLocked(r);
2589                }
2590            }
2591        }
2592    }
2593
2594    @Override
2595    public void notifyActivityDrawn(IBinder token) {
2596        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2597        synchronized (this) {
2598            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2599            if (r != null) {
2600                r.task.stack.notifyActivityDrawnLocked(r);
2601            }
2602        }
2603    }
2604
2605    final void applyUpdateLockStateLocked(ActivityRecord r) {
2606        // Modifications to the UpdateLock state are done on our handler, outside
2607        // the activity manager's locks.  The new state is determined based on the
2608        // state *now* of the relevant activity record.  The object is passed to
2609        // the handler solely for logging detail, not to be consulted/modified.
2610        final boolean nextState = r != null && r.immersive;
2611        mHandler.sendMessage(
2612                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2613    }
2614
2615    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2616        Message msg = Message.obtain();
2617        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2618        msg.obj = r.task.askedCompatMode ? null : r;
2619        mHandler.sendMessage(msg);
2620    }
2621
2622    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2623            String what, Object obj, ProcessRecord srcApp) {
2624        app.lastActivityTime = now;
2625
2626        if (app.activities.size() > 0) {
2627            // Don't want to touch dependent processes that are hosting activities.
2628            return index;
2629        }
2630
2631        int lrui = mLruProcesses.lastIndexOf(app);
2632        if (lrui < 0) {
2633            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2634                    + what + " " + obj + " from " + srcApp);
2635            return index;
2636        }
2637
2638        if (lrui >= index) {
2639            // Don't want to cause this to move dependent processes *back* in the
2640            // list as if they were less frequently used.
2641            return index;
2642        }
2643
2644        if (lrui >= mLruProcessActivityStart) {
2645            // Don't want to touch dependent processes that are hosting activities.
2646            return index;
2647        }
2648
2649        mLruProcesses.remove(lrui);
2650        if (index > 0) {
2651            index--;
2652        }
2653        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2654                + " in LRU list: " + app);
2655        mLruProcesses.add(index, app);
2656        return index;
2657    }
2658
2659    final void removeLruProcessLocked(ProcessRecord app) {
2660        int lrui = mLruProcesses.lastIndexOf(app);
2661        if (lrui >= 0) {
2662            if (!app.killed) {
2663                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2664                Process.killProcessQuiet(app.pid);
2665                Process.killProcessGroup(app.info.uid, app.pid);
2666            }
2667            if (lrui <= mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui <= mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            mLruProcesses.remove(lrui);
2674        }
2675    }
2676
2677    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2678            ProcessRecord client) {
2679        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2680                || app.treatLikeActivity;
2681        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2682        if (!activityChange && hasActivity) {
2683            // The process has activities, so we are only allowing activity-based adjustments
2684            // to move it.  It should be kept in the front of the list with other
2685            // processes that have activities, and we don't want those to change their
2686            // order except due to activity operations.
2687            return;
2688        }
2689
2690        mLruSeq++;
2691        final long now = SystemClock.uptimeMillis();
2692        app.lastActivityTime = now;
2693
2694        // First a quick reject: if the app is already at the position we will
2695        // put it, then there is nothing to do.
2696        if (hasActivity) {
2697            final int N = mLruProcesses.size();
2698            if (N > 0 && mLruProcesses.get(N-1) == app) {
2699                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2700                return;
2701            }
2702        } else {
2703            if (mLruProcessServiceStart > 0
2704                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2705                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2706                return;
2707            }
2708        }
2709
2710        int lrui = mLruProcesses.lastIndexOf(app);
2711
2712        if (app.persistent && lrui >= 0) {
2713            // We don't care about the position of persistent processes, as long as
2714            // they are in the list.
2715            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2716            return;
2717        }
2718
2719        /* In progress: compute new position first, so we can avoid doing work
2720           if the process is not actually going to move.  Not yet working.
2721        int addIndex;
2722        int nextIndex;
2723        boolean inActivity = false, inService = false;
2724        if (hasActivity) {
2725            // Process has activities, put it at the very tipsy-top.
2726            addIndex = mLruProcesses.size();
2727            nextIndex = mLruProcessServiceStart;
2728            inActivity = true;
2729        } else if (hasService) {
2730            // Process has services, put it at the top of the service list.
2731            addIndex = mLruProcessActivityStart;
2732            nextIndex = mLruProcessServiceStart;
2733            inActivity = true;
2734            inService = true;
2735        } else  {
2736            // Process not otherwise of interest, it goes to the top of the non-service area.
2737            addIndex = mLruProcessServiceStart;
2738            if (client != null) {
2739                int clientIndex = mLruProcesses.lastIndexOf(client);
2740                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2741                        + app);
2742                if (clientIndex >= 0 && addIndex > clientIndex) {
2743                    addIndex = clientIndex;
2744                }
2745            }
2746            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2747        }
2748
2749        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2750                + mLruProcessActivityStart + "): " + app);
2751        */
2752
2753        if (lrui >= 0) {
2754            if (lrui < mLruProcessActivityStart) {
2755                mLruProcessActivityStart--;
2756            }
2757            if (lrui < mLruProcessServiceStart) {
2758                mLruProcessServiceStart--;
2759            }
2760            /*
2761            if (addIndex > lrui) {
2762                addIndex--;
2763            }
2764            if (nextIndex > lrui) {
2765                nextIndex--;
2766            }
2767            */
2768            mLruProcesses.remove(lrui);
2769        }
2770
2771        /*
2772        mLruProcesses.add(addIndex, app);
2773        if (inActivity) {
2774            mLruProcessActivityStart++;
2775        }
2776        if (inService) {
2777            mLruProcessActivityStart++;
2778        }
2779        */
2780
2781        int nextIndex;
2782        if (hasActivity) {
2783            final int N = mLruProcesses.size();
2784            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2785                // Process doesn't have activities, but has clients with
2786                // activities...  move it up, but one below the top (the top
2787                // should always have a real activity).
2788                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2789                mLruProcesses.add(N-1, app);
2790                // To keep it from spamming the LRU list (by making a bunch of clients),
2791                // we will push down any other entries owned by the app.
2792                final int uid = app.info.uid;
2793                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2794                    ProcessRecord subProc = mLruProcesses.get(i);
2795                    if (subProc.info.uid == uid) {
2796                        // We want to push this one down the list.  If the process after
2797                        // it is for the same uid, however, don't do so, because we don't
2798                        // want them internally to be re-ordered.
2799                        if (mLruProcesses.get(i-1).info.uid != uid) {
2800                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2801                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2802                            ProcessRecord tmp = mLruProcesses.get(i);
2803                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2804                            mLruProcesses.set(i-1, tmp);
2805                            i--;
2806                        }
2807                    } else {
2808                        // A gap, we can stop here.
2809                        break;
2810                    }
2811                }
2812            } else {
2813                // Process has activities, put it at the very tipsy-top.
2814                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2815                mLruProcesses.add(app);
2816            }
2817            nextIndex = mLruProcessServiceStart;
2818        } else if (hasService) {
2819            // Process has services, put it at the top of the service list.
2820            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2821            mLruProcesses.add(mLruProcessActivityStart, app);
2822            nextIndex = mLruProcessServiceStart;
2823            mLruProcessActivityStart++;
2824        } else  {
2825            // Process not otherwise of interest, it goes to the top of the non-service area.
2826            int index = mLruProcessServiceStart;
2827            if (client != null) {
2828                // If there is a client, don't allow the process to be moved up higher
2829                // in the list than that client.
2830                int clientIndex = mLruProcesses.lastIndexOf(client);
2831                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2832                        + " when updating " + app);
2833                if (clientIndex <= lrui) {
2834                    // Don't allow the client index restriction to push it down farther in the
2835                    // list than it already is.
2836                    clientIndex = lrui;
2837                }
2838                if (clientIndex >= 0 && index > clientIndex) {
2839                    index = clientIndex;
2840                }
2841            }
2842            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2843            mLruProcesses.add(index, app);
2844            nextIndex = index-1;
2845            mLruProcessActivityStart++;
2846            mLruProcessServiceStart++;
2847        }
2848
2849        // If the app is currently using a content provider or service,
2850        // bump those processes as well.
2851        for (int j=app.connections.size()-1; j>=0; j--) {
2852            ConnectionRecord cr = app.connections.valueAt(j);
2853            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2854                    && cr.binding.service.app != null
2855                    && cr.binding.service.app.lruSeq != mLruSeq
2856                    && !cr.binding.service.app.persistent) {
2857                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2858                        "service connection", cr, app);
2859            }
2860        }
2861        for (int j=app.conProviders.size()-1; j>=0; j--) {
2862            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2863            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2864                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2865                        "provider reference", cpr, app);
2866            }
2867        }
2868    }
2869
2870    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2871        if (uid == Process.SYSTEM_UID) {
2872            // The system gets to run in any process.  If there are multiple
2873            // processes with the same uid, just pick the first (this
2874            // should never happen).
2875            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2876            if (procs == null) return null;
2877            final int N = procs.size();
2878            for (int i = 0; i < N; i++) {
2879                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2880            }
2881        }
2882        ProcessRecord proc = mProcessNames.get(processName, uid);
2883        if (false && proc != null && !keepIfLarge
2884                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2885                && proc.lastCachedPss >= 4000) {
2886            // Turn this condition on to cause killing to happen regularly, for testing.
2887            if (proc.baseProcessTracker != null) {
2888                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2889            }
2890            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2891        } else if (proc != null && !keepIfLarge
2892                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2893                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2894            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2895            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2896                if (proc.baseProcessTracker != null) {
2897                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2898                }
2899                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2900            }
2901        }
2902        return proc;
2903    }
2904
2905    void ensurePackageDexOpt(String packageName) {
2906        IPackageManager pm = AppGlobals.getPackageManager();
2907        try {
2908            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2909                mDidDexOpt = true;
2910            }
2911        } catch (RemoteException e) {
2912        }
2913    }
2914
2915    boolean isNextTransitionForward() {
2916        int transit = mWindowManager.getPendingAppTransition();
2917        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2918                || transit == AppTransition.TRANSIT_TASK_OPEN
2919                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2920    }
2921
2922    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2923            String processName, String abiOverride, int uid, Runnable crashHandler) {
2924        synchronized(this) {
2925            ApplicationInfo info = new ApplicationInfo();
2926            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2927            // For isolated processes, the former contains the parent's uid and the latter the
2928            // actual uid of the isolated process.
2929            // In the special case introduced by this method (which is, starting an isolated
2930            // process directly from the SystemServer without an actual parent app process) the
2931            // closest thing to a parent's uid is SYSTEM_UID.
2932            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2933            // the |isolated| logic in the ProcessRecord constructor.
2934            info.uid = Process.SYSTEM_UID;
2935            info.processName = processName;
2936            info.className = entryPoint;
2937            info.packageName = "android";
2938            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2939                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2940                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2941                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2942                    crashHandler);
2943            return proc != null ? proc.pid : 0;
2944        }
2945    }
2946
2947    final ProcessRecord startProcessLocked(String processName,
2948            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2949            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2950            boolean isolated, boolean keepIfLarge) {
2951        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2952                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2953                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2954                null /* crashHandler */);
2955    }
2956
2957    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2958            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2959            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2960            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2961        long startTime = SystemClock.elapsedRealtime();
2962        ProcessRecord app;
2963        if (!isolated) {
2964            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2965            checkTime(startTime, "startProcess: after getProcessRecord");
2966        } else {
2967            // If this is an isolated process, it can't re-use an existing process.
2968            app = null;
2969        }
2970        // We don't have to do anything more if:
2971        // (1) There is an existing application record; and
2972        // (2) The caller doesn't think it is dead, OR there is no thread
2973        //     object attached to it so we know it couldn't have crashed; and
2974        // (3) There is a pid assigned to it, so it is either starting or
2975        //     already running.
2976        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2977                + " app=" + app + " knownToBeDead=" + knownToBeDead
2978                + " thread=" + (app != null ? app.thread : null)
2979                + " pid=" + (app != null ? app.pid : -1));
2980        if (app != null && app.pid > 0) {
2981            if (!knownToBeDead || app.thread == null) {
2982                // We already have the app running, or are waiting for it to
2983                // come up (we have a pid but not yet its thread), so keep it.
2984                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2985                // If this is a new package in the process, add the package to the list
2986                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2987                checkTime(startTime, "startProcess: done, added package to proc");
2988                return app;
2989            }
2990
2991            // An application record is attached to a previous process,
2992            // clean it up now.
2993            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2994            checkTime(startTime, "startProcess: bad proc running, killing");
2995            Process.killProcessGroup(app.info.uid, app.pid);
2996            handleAppDiedLocked(app, true, true);
2997            checkTime(startTime, "startProcess: done killing old proc");
2998        }
2999
3000        String hostingNameStr = hostingName != null
3001                ? hostingName.flattenToShortString() : null;
3002
3003        if (!isolated) {
3004            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3005                // If we are in the background, then check to see if this process
3006                // is bad.  If so, we will just silently fail.
3007                if (mBadProcesses.get(info.processName, info.uid) != null) {
3008                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3009                            + "/" + info.processName);
3010                    return null;
3011                }
3012            } else {
3013                // When the user is explicitly starting a process, then clear its
3014                // crash count so that we won't make it bad until they see at
3015                // least one crash dialog again, and make the process good again
3016                // if it had been bad.
3017                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3018                        + "/" + info.processName);
3019                mProcessCrashTimes.remove(info.processName, info.uid);
3020                if (mBadProcesses.get(info.processName, info.uid) != null) {
3021                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3022                            UserHandle.getUserId(info.uid), info.uid,
3023                            info.processName);
3024                    mBadProcesses.remove(info.processName, info.uid);
3025                    if (app != null) {
3026                        app.bad = false;
3027                    }
3028                }
3029            }
3030        }
3031
3032        if (app == null) {
3033            checkTime(startTime, "startProcess: creating new process record");
3034            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3035            app.crashHandler = crashHandler;
3036            if (app == null) {
3037                Slog.w(TAG, "Failed making new process record for "
3038                        + processName + "/" + info.uid + " isolated=" + isolated);
3039                return null;
3040            }
3041            mProcessNames.put(processName, app.uid, app);
3042            if (isolated) {
3043                mIsolatedProcesses.put(app.uid, app);
3044            }
3045            checkTime(startTime, "startProcess: done creating new process record");
3046        } else {
3047            // If this is a new package in the process, add the package to the list
3048            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3049            checkTime(startTime, "startProcess: added package to existing proc");
3050        }
3051
3052        // If the system is not ready yet, then hold off on starting this
3053        // process until it is.
3054        if (!mProcessesReady
3055                && !isAllowedWhileBooting(info)
3056                && !allowWhileBooting) {
3057            if (!mProcessesOnHold.contains(app)) {
3058                mProcessesOnHold.add(app);
3059            }
3060            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3061            checkTime(startTime, "startProcess: returning with proc on hold");
3062            return app;
3063        }
3064
3065        checkTime(startTime, "startProcess: stepping in to startProcess");
3066        startProcessLocked(
3067                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3068        checkTime(startTime, "startProcess: done starting proc!");
3069        return (app.pid != 0) ? app : null;
3070    }
3071
3072    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3073        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3074    }
3075
3076    private final void startProcessLocked(ProcessRecord app,
3077            String hostingType, String hostingNameStr) {
3078        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3079                null /* entryPoint */, null /* entryPointArgs */);
3080    }
3081
3082    private final void startProcessLocked(ProcessRecord app, String hostingType,
3083            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3084        long startTime = SystemClock.elapsedRealtime();
3085        if (app.pid > 0 && app.pid != MY_PID) {
3086            checkTime(startTime, "startProcess: removing from pids map");
3087            synchronized (mPidsSelfLocked) {
3088                mPidsSelfLocked.remove(app.pid);
3089                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3090            }
3091            checkTime(startTime, "startProcess: done removing from pids map");
3092            app.setPid(0);
3093        }
3094
3095        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3096                "startProcessLocked removing on hold: " + app);
3097        mProcessesOnHold.remove(app);
3098
3099        checkTime(startTime, "startProcess: starting to update cpu stats");
3100        updateCpuStats();
3101        checkTime(startTime, "startProcess: done updating cpu stats");
3102
3103        try {
3104            int uid = app.uid;
3105
3106            int[] gids = null;
3107            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3108            if (!app.isolated) {
3109                int[] permGids = null;
3110                try {
3111                    checkTime(startTime, "startProcess: getting gids from package manager");
3112                    final PackageManager pm = mContext.getPackageManager();
3113                    permGids = pm.getPackageGids(app.info.packageName);
3114
3115                    if (Environment.isExternalStorageEmulated()) {
3116                        checkTime(startTime, "startProcess: checking external storage perm");
3117                        if (pm.checkPermission(
3118                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3119                                app.info.packageName) == PERMISSION_GRANTED) {
3120                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3121                        } else {
3122                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3123                        }
3124                    }
3125                } catch (PackageManager.NameNotFoundException e) {
3126                    Slog.w(TAG, "Unable to retrieve gids", e);
3127                }
3128
3129                /*
3130                 * Add shared application and profile GIDs so applications can share some
3131                 * resources like shared libraries and access user-wide resources
3132                 */
3133                if (permGids == null) {
3134                    gids = new int[2];
3135                } else {
3136                    gids = new int[permGids.length + 2];
3137                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3138                }
3139                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3140                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3141            }
3142            checkTime(startTime, "startProcess: building args");
3143            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3144                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3145                        && mTopComponent != null
3146                        && app.processName.equals(mTopComponent.getPackageName())) {
3147                    uid = 0;
3148                }
3149                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3150                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3151                    uid = 0;
3152                }
3153            }
3154            int debugFlags = 0;
3155            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3156                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3157                // Also turn on CheckJNI for debuggable apps. It's quite
3158                // awkward to turn on otherwise.
3159                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3160            }
3161            // Run the app in safe mode if its manifest requests so or the
3162            // system is booted in safe mode.
3163            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3164                mSafeMode == true) {
3165                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3166            }
3167            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3168                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3169            }
3170            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3171                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3172            }
3173            if ("1".equals(SystemProperties.get("debug.assert"))) {
3174                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3175            }
3176
3177            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3178            if (requiredAbi == null) {
3179                requiredAbi = Build.SUPPORTED_ABIS[0];
3180            }
3181
3182            String instructionSet = null;
3183            if (app.info.primaryCpuAbi != null) {
3184                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3185            }
3186
3187            // Start the process.  It will either succeed and return a result containing
3188            // the PID of the new process, or else throw a RuntimeException.
3189            boolean isActivityProcess = (entryPoint == null);
3190            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3191            checkTime(startTime, "startProcess: asking zygote to start proc");
3192            Process.ProcessStartResult startResult = Process.start(entryPoint,
3193                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3194                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3195                    app.info.dataDir, entryPointArgs);
3196            checkTime(startTime, "startProcess: returned from zygote!");
3197
3198            if (app.isolated) {
3199                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3200            }
3201            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3202            checkTime(startTime, "startProcess: done updating battery stats");
3203
3204            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3205                    UserHandle.getUserId(uid), startResult.pid, uid,
3206                    app.processName, hostingType,
3207                    hostingNameStr != null ? hostingNameStr : "");
3208
3209            if (app.persistent) {
3210                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3211            }
3212
3213            checkTime(startTime, "startProcess: building log message");
3214            StringBuilder buf = mStringBuilder;
3215            buf.setLength(0);
3216            buf.append("Start proc ");
3217            buf.append(app.processName);
3218            if (!isActivityProcess) {
3219                buf.append(" [");
3220                buf.append(entryPoint);
3221                buf.append("]");
3222            }
3223            buf.append(" for ");
3224            buf.append(hostingType);
3225            if (hostingNameStr != null) {
3226                buf.append(" ");
3227                buf.append(hostingNameStr);
3228            }
3229            buf.append(": pid=");
3230            buf.append(startResult.pid);
3231            buf.append(" uid=");
3232            buf.append(uid);
3233            buf.append(" gids={");
3234            if (gids != null) {
3235                for (int gi=0; gi<gids.length; gi++) {
3236                    if (gi != 0) buf.append(", ");
3237                    buf.append(gids[gi]);
3238
3239                }
3240            }
3241            buf.append("}");
3242            if (requiredAbi != null) {
3243                buf.append(" abi=");
3244                buf.append(requiredAbi);
3245            }
3246            Slog.i(TAG, buf.toString());
3247            app.setPid(startResult.pid);
3248            app.usingWrapper = startResult.usingWrapper;
3249            app.removed = false;
3250            app.killed = false;
3251            app.killedByAm = false;
3252            checkTime(startTime, "startProcess: starting to update pids map");
3253            synchronized (mPidsSelfLocked) {
3254                this.mPidsSelfLocked.put(startResult.pid, app);
3255                if (isActivityProcess) {
3256                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3257                    msg.obj = app;
3258                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3259                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3260                }
3261            }
3262            checkTime(startTime, "startProcess: done updating pids map");
3263        } catch (RuntimeException e) {
3264            // XXX do better error recovery.
3265            app.setPid(0);
3266            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3267            if (app.isolated) {
3268                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3269            }
3270            Slog.e(TAG, "Failure starting process " + app.processName, e);
3271        }
3272    }
3273
3274    void updateUsageStats(ActivityRecord component, boolean resumed) {
3275        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3276        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3277        if (resumed) {
3278            if (mUsageStatsService != null) {
3279                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3280                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3281            }
3282            synchronized (stats) {
3283                stats.noteActivityResumedLocked(component.app.uid);
3284            }
3285        } else {
3286            if (mUsageStatsService != null) {
3287                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3288                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3289            }
3290            synchronized (stats) {
3291                stats.noteActivityPausedLocked(component.app.uid);
3292            }
3293        }
3294    }
3295
3296    Intent getHomeIntent() {
3297        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3298        intent.setComponent(mTopComponent);
3299        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3300            intent.addCategory(Intent.CATEGORY_HOME);
3301        }
3302        return intent;
3303    }
3304
3305    boolean startHomeActivityLocked(int userId) {
3306        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3307                && mTopAction == null) {
3308            // We are running in factory test mode, but unable to find
3309            // the factory test app, so just sit around displaying the
3310            // error message and don't try to start anything.
3311            return false;
3312        }
3313        Intent intent = getHomeIntent();
3314        ActivityInfo aInfo =
3315            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3316        if (aInfo != null) {
3317            intent.setComponent(new ComponentName(
3318                    aInfo.applicationInfo.packageName, aInfo.name));
3319            // Don't do this if the home app is currently being
3320            // instrumented.
3321            aInfo = new ActivityInfo(aInfo);
3322            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3323            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3324                    aInfo.applicationInfo.uid, true);
3325            if (app == null || app.instrumentationClass == null) {
3326                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3327                mStackSupervisor.startHomeActivity(intent, aInfo);
3328            }
3329        }
3330
3331        return true;
3332    }
3333
3334    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3335        ActivityInfo ai = null;
3336        ComponentName comp = intent.getComponent();
3337        try {
3338            if (comp != null) {
3339                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3340            } else {
3341                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3342                        intent,
3343                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3344                            flags, userId);
3345
3346                if (info != null) {
3347                    ai = info.activityInfo;
3348                }
3349            }
3350        } catch (RemoteException e) {
3351            // ignore
3352        }
3353
3354        return ai;
3355    }
3356
3357    /**
3358     * Starts the "new version setup screen" if appropriate.
3359     */
3360    void startSetupActivityLocked() {
3361        // Only do this once per boot.
3362        if (mCheckedForSetup) {
3363            return;
3364        }
3365
3366        // We will show this screen if the current one is a different
3367        // version than the last one shown, and we are not running in
3368        // low-level factory test mode.
3369        final ContentResolver resolver = mContext.getContentResolver();
3370        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3371                Settings.Global.getInt(resolver,
3372                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3373            mCheckedForSetup = true;
3374
3375            // See if we should be showing the platform update setup UI.
3376            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3377            List<ResolveInfo> ris = mContext.getPackageManager()
3378                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3379
3380            // We don't allow third party apps to replace this.
3381            ResolveInfo ri = null;
3382            for (int i=0; ris != null && i<ris.size(); i++) {
3383                if ((ris.get(i).activityInfo.applicationInfo.flags
3384                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3385                    ri = ris.get(i);
3386                    break;
3387                }
3388            }
3389
3390            if (ri != null) {
3391                String vers = ri.activityInfo.metaData != null
3392                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3393                        : null;
3394                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3395                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3396                            Intent.METADATA_SETUP_VERSION);
3397                }
3398                String lastVers = Settings.Secure.getString(
3399                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3400                if (vers != null && !vers.equals(lastVers)) {
3401                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3402                    intent.setComponent(new ComponentName(
3403                            ri.activityInfo.packageName, ri.activityInfo.name));
3404                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3405                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3406                            null);
3407                }
3408            }
3409        }
3410    }
3411
3412    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3413        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3414    }
3415
3416    void enforceNotIsolatedCaller(String caller) {
3417        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3418            throw new SecurityException("Isolated process not allowed to call " + caller);
3419        }
3420    }
3421
3422    void enforceShellRestriction(String restriction, int userHandle) {
3423        if (Binder.getCallingUid() == Process.SHELL_UID) {
3424            if (userHandle < 0
3425                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3426                throw new SecurityException("Shell does not have permission to access user "
3427                        + userHandle);
3428            }
3429        }
3430    }
3431
3432    @Override
3433    public int getFrontActivityScreenCompatMode() {
3434        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3435        synchronized (this) {
3436            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3437        }
3438    }
3439
3440    @Override
3441    public void setFrontActivityScreenCompatMode(int mode) {
3442        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3443                "setFrontActivityScreenCompatMode");
3444        synchronized (this) {
3445            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3446        }
3447    }
3448
3449    @Override
3450    public int getPackageScreenCompatMode(String packageName) {
3451        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3452        synchronized (this) {
3453            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3454        }
3455    }
3456
3457    @Override
3458    public void setPackageScreenCompatMode(String packageName, int mode) {
3459        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3460                "setPackageScreenCompatMode");
3461        synchronized (this) {
3462            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3463        }
3464    }
3465
3466    @Override
3467    public boolean getPackageAskScreenCompat(String packageName) {
3468        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3469        synchronized (this) {
3470            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3471        }
3472    }
3473
3474    @Override
3475    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3476        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3477                "setPackageAskScreenCompat");
3478        synchronized (this) {
3479            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3480        }
3481    }
3482
3483    private void dispatchProcessesChanged() {
3484        int N;
3485        synchronized (this) {
3486            N = mPendingProcessChanges.size();
3487            if (mActiveProcessChanges.length < N) {
3488                mActiveProcessChanges = new ProcessChangeItem[N];
3489            }
3490            mPendingProcessChanges.toArray(mActiveProcessChanges);
3491            mAvailProcessChanges.addAll(mPendingProcessChanges);
3492            mPendingProcessChanges.clear();
3493            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3494        }
3495
3496        int i = mProcessObservers.beginBroadcast();
3497        while (i > 0) {
3498            i--;
3499            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3500            if (observer != null) {
3501                try {
3502                    for (int j=0; j<N; j++) {
3503                        ProcessChangeItem item = mActiveProcessChanges[j];
3504                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3505                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3506                                    + item.pid + " uid=" + item.uid + ": "
3507                                    + item.foregroundActivities);
3508                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3509                                    item.foregroundActivities);
3510                        }
3511                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3512                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3513                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3514                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3515                        }
3516                    }
3517                } catch (RemoteException e) {
3518                }
3519            }
3520        }
3521        mProcessObservers.finishBroadcast();
3522    }
3523
3524    private void dispatchProcessDied(int pid, int uid) {
3525        int i = mProcessObservers.beginBroadcast();
3526        while (i > 0) {
3527            i--;
3528            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3529            if (observer != null) {
3530                try {
3531                    observer.onProcessDied(pid, uid);
3532                } catch (RemoteException e) {
3533                }
3534            }
3535        }
3536        mProcessObservers.finishBroadcast();
3537    }
3538
3539    @Override
3540    public final int startActivity(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3543        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3544            resultWho, requestCode, startFlags, profilerInfo, options,
3545            UserHandle.getCallingUserId());
3546    }
3547
3548    @Override
3549    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3550            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3551            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3552        enforceNotIsolatedCaller("startActivity");
3553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3554                false, ALLOW_FULL_ONLY, "startActivity", null);
3555        // TODO: Switch to user app stacks here.
3556        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3557                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3558                profilerInfo, null, null, options, userId, null, null);
3559    }
3560
3561    @Override
3562    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3563            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3564            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3565
3566        // This is very dangerous -- it allows you to perform a start activity (including
3567        // permission grants) as any app that may launch one of your own activities.  So
3568        // we will only allow this to be done from activities that are part of the core framework,
3569        // and then only when they are running as the system.
3570        final ActivityRecord sourceRecord;
3571        final int targetUid;
3572        final String targetPackage;
3573        synchronized (this) {
3574            if (resultTo == null) {
3575                throw new SecurityException("Must be called from an activity");
3576            }
3577            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3578            if (sourceRecord == null) {
3579                throw new SecurityException("Called with bad activity token: " + resultTo);
3580            }
3581            if (!sourceRecord.info.packageName.equals("android")) {
3582                throw new SecurityException(
3583                        "Must be called from an activity that is declared in the android package");
3584            }
3585            if (sourceRecord.app == null) {
3586                throw new SecurityException("Called without a process attached to activity");
3587            }
3588            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3589                // This is still okay, as long as this activity is running under the
3590                // uid of the original calling activity.
3591                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3592                    throw new SecurityException(
3593                            "Calling activity in uid " + sourceRecord.app.uid
3594                                    + " must be system uid or original calling uid "
3595                                    + sourceRecord.launchedFromUid);
3596                }
3597            }
3598            targetUid = sourceRecord.launchedFromUid;
3599            targetPackage = sourceRecord.launchedFromPackage;
3600        }
3601
3602        if (userId == UserHandle.USER_NULL) {
3603            userId = UserHandle.getUserId(sourceRecord.app.uid);
3604        }
3605
3606        // TODO: Switch to user app stacks here.
3607        try {
3608            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3609                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3610                    null, null, options, userId, null, null);
3611            return ret;
3612        } catch (SecurityException e) {
3613            // XXX need to figure out how to propagate to original app.
3614            // A SecurityException here is generally actually a fault of the original
3615            // calling activity (such as a fairly granting permissions), so propagate it
3616            // back to them.
3617            /*
3618            StringBuilder msg = new StringBuilder();
3619            msg.append("While launching");
3620            msg.append(intent.toString());
3621            msg.append(": ");
3622            msg.append(e.getMessage());
3623            */
3624            throw e;
3625        }
3626    }
3627
3628    @Override
3629    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3630            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3631            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3632        enforceNotIsolatedCaller("startActivityAndWait");
3633        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3634                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3635        WaitResult res = new WaitResult();
3636        // TODO: Switch to user app stacks here.
3637        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3638                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3639                options, userId, null, null);
3640        return res;
3641    }
3642
3643    @Override
3644    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3645            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3646            int startFlags, Configuration config, Bundle options, int userId) {
3647        enforceNotIsolatedCaller("startActivityWithConfig");
3648        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3649                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3650        // TODO: Switch to user app stacks here.
3651        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3652                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3653                null, null, config, options, userId, null, null);
3654        return ret;
3655    }
3656
3657    @Override
3658    public int startActivityIntentSender(IApplicationThread caller,
3659            IntentSender intent, Intent fillInIntent, String resolvedType,
3660            IBinder resultTo, String resultWho, int requestCode,
3661            int flagsMask, int flagsValues, Bundle options) {
3662        enforceNotIsolatedCaller("startActivityIntentSender");
3663        // Refuse possible leaked file descriptors
3664        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3665            throw new IllegalArgumentException("File descriptors passed in Intent");
3666        }
3667
3668        IIntentSender sender = intent.getTarget();
3669        if (!(sender instanceof PendingIntentRecord)) {
3670            throw new IllegalArgumentException("Bad PendingIntent object");
3671        }
3672
3673        PendingIntentRecord pir = (PendingIntentRecord)sender;
3674
3675        synchronized (this) {
3676            // If this is coming from the currently resumed activity, it is
3677            // effectively saying that app switches are allowed at this point.
3678            final ActivityStack stack = getFocusedStack();
3679            if (stack.mResumedActivity != null &&
3680                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3681                mAppSwitchesAllowedTime = 0;
3682            }
3683        }
3684        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3685                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3686        return ret;
3687    }
3688
3689    @Override
3690    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3691            Intent intent, String resolvedType, IVoiceInteractionSession session,
3692            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3693            Bundle options, int userId) {
3694        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3695                != PackageManager.PERMISSION_GRANTED) {
3696            String msg = "Permission Denial: startVoiceActivity() from pid="
3697                    + Binder.getCallingPid()
3698                    + ", uid=" + Binder.getCallingUid()
3699                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3700            Slog.w(TAG, msg);
3701            throw new SecurityException(msg);
3702        }
3703        if (session == null || interactor == null) {
3704            throw new NullPointerException("null session or interactor");
3705        }
3706        userId = handleIncomingUser(callingPid, callingUid, userId,
3707                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3708        // TODO: Switch to user app stacks here.
3709        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3710                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3711                null, options, userId, null, null);
3712    }
3713
3714    @Override
3715    public boolean startNextMatchingActivity(IBinder callingActivity,
3716            Intent intent, Bundle options) {
3717        // Refuse possible leaked file descriptors
3718        if (intent != null && intent.hasFileDescriptors() == true) {
3719            throw new IllegalArgumentException("File descriptors passed in Intent");
3720        }
3721
3722        synchronized (this) {
3723            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3724            if (r == null) {
3725                ActivityOptions.abort(options);
3726                return false;
3727            }
3728            if (r.app == null || r.app.thread == null) {
3729                // The caller is not running...  d'oh!
3730                ActivityOptions.abort(options);
3731                return false;
3732            }
3733            intent = new Intent(intent);
3734            // The caller is not allowed to change the data.
3735            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3736            // And we are resetting to find the next component...
3737            intent.setComponent(null);
3738
3739            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3740
3741            ActivityInfo aInfo = null;
3742            try {
3743                List<ResolveInfo> resolves =
3744                    AppGlobals.getPackageManager().queryIntentActivities(
3745                            intent, r.resolvedType,
3746                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3747                            UserHandle.getCallingUserId());
3748
3749                // Look for the original activity in the list...
3750                final int N = resolves != null ? resolves.size() : 0;
3751                for (int i=0; i<N; i++) {
3752                    ResolveInfo rInfo = resolves.get(i);
3753                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3754                            && rInfo.activityInfo.name.equals(r.info.name)) {
3755                        // We found the current one...  the next matching is
3756                        // after it.
3757                        i++;
3758                        if (i<N) {
3759                            aInfo = resolves.get(i).activityInfo;
3760                        }
3761                        if (debug) {
3762                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3763                                    + "/" + r.info.name);
3764                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3765                                    + "/" + aInfo.name);
3766                        }
3767                        break;
3768                    }
3769                }
3770            } catch (RemoteException e) {
3771            }
3772
3773            if (aInfo == null) {
3774                // Nobody who is next!
3775                ActivityOptions.abort(options);
3776                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3777                return false;
3778            }
3779
3780            intent.setComponent(new ComponentName(
3781                    aInfo.applicationInfo.packageName, aInfo.name));
3782            intent.setFlags(intent.getFlags()&~(
3783                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3784                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3785                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3786                    Intent.FLAG_ACTIVITY_NEW_TASK));
3787
3788            // Okay now we need to start the new activity, replacing the
3789            // currently running activity.  This is a little tricky because
3790            // we want to start the new one as if the current one is finished,
3791            // but not finish the current one first so that there is no flicker.
3792            // And thus...
3793            final boolean wasFinishing = r.finishing;
3794            r.finishing = true;
3795
3796            // Propagate reply information over to the new activity.
3797            final ActivityRecord resultTo = r.resultTo;
3798            final String resultWho = r.resultWho;
3799            final int requestCode = r.requestCode;
3800            r.resultTo = null;
3801            if (resultTo != null) {
3802                resultTo.removeResultsLocked(r, resultWho, requestCode);
3803            }
3804
3805            final long origId = Binder.clearCallingIdentity();
3806            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3807                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3808                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3809                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3810            Binder.restoreCallingIdentity(origId);
3811
3812            r.finishing = wasFinishing;
3813            if (res != ActivityManager.START_SUCCESS) {
3814                return false;
3815            }
3816            return true;
3817        }
3818    }
3819
3820    @Override
3821    public final int startActivityFromRecents(int taskId, Bundle options) {
3822        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3823            String msg = "Permission Denial: startActivityFromRecents called without " +
3824                    START_TASKS_FROM_RECENTS;
3825            Slog.w(TAG, msg);
3826            throw new SecurityException(msg);
3827        }
3828        return startActivityFromRecentsInner(taskId, options);
3829    }
3830
3831    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3832        final TaskRecord task;
3833        final int callingUid;
3834        final String callingPackage;
3835        final Intent intent;
3836        final int userId;
3837        synchronized (this) {
3838            task = recentTaskForIdLocked(taskId);
3839            if (task == null) {
3840                throw new IllegalArgumentException("Task " + taskId + " not found.");
3841            }
3842            callingUid = task.mCallingUid;
3843            callingPackage = task.mCallingPackage;
3844            intent = task.intent;
3845            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3846            userId = task.userId;
3847        }
3848        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3849                options, userId, null, task);
3850    }
3851
3852    final int startActivityInPackage(int uid, String callingPackage,
3853            Intent intent, String resolvedType, IBinder resultTo,
3854            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3855            IActivityContainer container, TaskRecord inTask) {
3856
3857        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3858                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3859
3860        // TODO: Switch to user app stacks here.
3861        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3862                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3863                null, null, null, options, userId, container, inTask);
3864        return ret;
3865    }
3866
3867    @Override
3868    public final int startActivities(IApplicationThread caller, String callingPackage,
3869            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3870            int userId) {
3871        enforceNotIsolatedCaller("startActivities");
3872        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3873                false, ALLOW_FULL_ONLY, "startActivity", null);
3874        // TODO: Switch to user app stacks here.
3875        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3876                resolvedTypes, resultTo, options, userId);
3877        return ret;
3878    }
3879
3880    final int startActivitiesInPackage(int uid, String callingPackage,
3881            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3882            Bundle options, int userId) {
3883
3884        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3885                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3886        // TODO: Switch to user app stacks here.
3887        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3888                resultTo, options, userId);
3889        return ret;
3890    }
3891
3892    //explicitly remove thd old information in mRecentTasks when removing existing user.
3893    private void removeRecentTasksForUserLocked(int userId) {
3894        if(userId <= 0) {
3895            Slog.i(TAG, "Can't remove recent task on user " + userId);
3896            return;
3897        }
3898
3899        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3900            TaskRecord tr = mRecentTasks.get(i);
3901            if (tr.userId == userId) {
3902                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3903                        + " when finishing user" + userId);
3904                mRecentTasks.remove(i);
3905                tr.removedFromRecents(mTaskPersister);
3906            }
3907        }
3908
3909        // Remove tasks from persistent storage.
3910        mTaskPersister.wakeup(null, true);
3911    }
3912
3913    // Sort by taskId
3914    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3915        @Override
3916        public int compare(TaskRecord lhs, TaskRecord rhs) {
3917            return rhs.taskId - lhs.taskId;
3918        }
3919    };
3920
3921    // Extract the affiliates of the chain containing mRecentTasks[start].
3922    private int processNextAffiliateChain(int start) {
3923        final TaskRecord startTask = mRecentTasks.get(start);
3924        final int affiliateId = startTask.mAffiliatedTaskId;
3925
3926        // Quick identification of isolated tasks. I.e. those not launched behind.
3927        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3928                startTask.mNextAffiliate == null) {
3929            // There is still a slim chance that there are other tasks that point to this task
3930            // and that the chain is so messed up that this task no longer points to them but
3931            // the gain of this optimization outweighs the risk.
3932            startTask.inRecents = true;
3933            return start + 1;
3934        }
3935
3936        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3937        mTmpRecents.clear();
3938        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3939            final TaskRecord task = mRecentTasks.get(i);
3940            if (task.mAffiliatedTaskId == affiliateId) {
3941                mRecentTasks.remove(i);
3942                mTmpRecents.add(task);
3943            }
3944        }
3945
3946        // Sort them all by taskId. That is the order they were create in and that order will
3947        // always be correct.
3948        Collections.sort(mTmpRecents, mTaskRecordComparator);
3949
3950        // Go through and fix up the linked list.
3951        // The first one is the end of the chain and has no next.
3952        final TaskRecord first = mTmpRecents.get(0);
3953        first.inRecents = true;
3954        if (first.mNextAffiliate != null) {
3955            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3956            first.setNextAffiliate(null);
3957            mTaskPersister.wakeup(first, false);
3958        }
3959        // Everything in the middle is doubly linked from next to prev.
3960        final int tmpSize = mTmpRecents.size();
3961        for (int i = 0; i < tmpSize - 1; ++i) {
3962            final TaskRecord next = mTmpRecents.get(i);
3963            final TaskRecord prev = mTmpRecents.get(i + 1);
3964            if (next.mPrevAffiliate != prev) {
3965                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3966                        " setting prev=" + prev);
3967                next.setPrevAffiliate(prev);
3968                mTaskPersister.wakeup(next, false);
3969            }
3970            if (prev.mNextAffiliate != next) {
3971                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3972                        " setting next=" + next);
3973                prev.setNextAffiliate(next);
3974                mTaskPersister.wakeup(prev, false);
3975            }
3976            prev.inRecents = true;
3977        }
3978        // The last one is the beginning of the list and has no prev.
3979        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3980        if (last.mPrevAffiliate != null) {
3981            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3982            last.setPrevAffiliate(null);
3983            mTaskPersister.wakeup(last, false);
3984        }
3985
3986        // Insert the group back into mRecentTasks at start.
3987        mRecentTasks.addAll(start, mTmpRecents);
3988
3989        // Let the caller know where we left off.
3990        return start + tmpSize;
3991    }
3992
3993    /**
3994     * Update the recent tasks lists: make sure tasks should still be here (their
3995     * applications / activities still exist), update their availability, fixup ordering
3996     * of affiliations.
3997     */
3998    void cleanupRecentTasksLocked(int userId) {
3999        if (mRecentTasks == null) {
4000            // Happens when called from the packagemanager broadcast before boot.
4001            return;
4002        }
4003
4004        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4005        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4006        final IPackageManager pm = AppGlobals.getPackageManager();
4007        final ActivityInfo dummyAct = new ActivityInfo();
4008        final ApplicationInfo dummyApp = new ApplicationInfo();
4009
4010        int N = mRecentTasks.size();
4011
4012        int[] users = userId == UserHandle.USER_ALL
4013                ? getUsersLocked() : new int[] { userId };
4014        for (int user : users) {
4015            for (int i = 0; i < N; i++) {
4016                TaskRecord task = mRecentTasks.get(i);
4017                if (task.userId != user) {
4018                    // Only look at tasks for the user ID of interest.
4019                    continue;
4020                }
4021                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4022                    // This situation is broken, and we should just get rid of it now.
4023                    mRecentTasks.remove(i);
4024                    task.removedFromRecents(mTaskPersister);
4025                    i--;
4026                    N--;
4027                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4028                    continue;
4029                }
4030                // Check whether this activity is currently available.
4031                if (task.realActivity != null) {
4032                    ActivityInfo ai = availActCache.get(task.realActivity);
4033                    if (ai == null) {
4034                        try {
4035                            ai = pm.getActivityInfo(task.realActivity,
4036                                    PackageManager.GET_UNINSTALLED_PACKAGES
4037                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4038                        } catch (RemoteException e) {
4039                            // Will never happen.
4040                            continue;
4041                        }
4042                        if (ai == null) {
4043                            ai = dummyAct;
4044                        }
4045                        availActCache.put(task.realActivity, ai);
4046                    }
4047                    if (ai == dummyAct) {
4048                        // This could be either because the activity no longer exists, or the
4049                        // app is temporarily gone.  For the former we want to remove the recents
4050                        // entry; for the latter we want to mark it as unavailable.
4051                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4052                        if (app == null) {
4053                            try {
4054                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4055                                        PackageManager.GET_UNINSTALLED_PACKAGES
4056                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4057                            } catch (RemoteException e) {
4058                                // Will never happen.
4059                                continue;
4060                            }
4061                            if (app == null) {
4062                                app = dummyApp;
4063                            }
4064                            availAppCache.put(task.realActivity.getPackageName(), app);
4065                        }
4066                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4067                            // Doesn't exist any more!  Good-bye.
4068                            mRecentTasks.remove(i);
4069                            task.removedFromRecents(mTaskPersister);
4070                            i--;
4071                            N--;
4072                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4073                            continue;
4074                        } else {
4075                            // Otherwise just not available for now.
4076                            if (task.isAvailable) {
4077                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4078                                        + task);
4079                            }
4080                            task.isAvailable = false;
4081                        }
4082                    } else {
4083                        if (!ai.enabled || !ai.applicationInfo.enabled
4084                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4085                            if (task.isAvailable) {
4086                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4087                                        + task + " (enabled=" + ai.enabled + "/"
4088                                        + ai.applicationInfo.enabled +  " flags="
4089                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4090                            }
4091                            task.isAvailable = false;
4092                        } else {
4093                            if (!task.isAvailable) {
4094                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4095                                        + task);
4096                            }
4097                            task.isAvailable = true;
4098                        }
4099                    }
4100                }
4101            }
4102        }
4103
4104        // Verify the affiliate chain for each task.
4105        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4106        }
4107
4108        mTmpRecents.clear();
4109        // mRecentTasks is now in sorted, affiliated order.
4110    }
4111
4112    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4113        int N = mRecentTasks.size();
4114        TaskRecord top = task;
4115        int topIndex = taskIndex;
4116        while (top.mNextAffiliate != null && topIndex > 0) {
4117            top = top.mNextAffiliate;
4118            topIndex--;
4119        }
4120        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4121                + topIndex + " from intial " + taskIndex);
4122        // Find the end of the chain, doing a sanity check along the way.
4123        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4124        int endIndex = topIndex;
4125        TaskRecord prev = top;
4126        while (endIndex < N) {
4127            TaskRecord cur = mRecentTasks.get(endIndex);
4128            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4129                    + endIndex + " " + cur);
4130            if (cur == top) {
4131                // Verify start of the chain.
4132                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4133                    Slog.wtf(TAG, "Bad chain @" + endIndex
4134                            + ": first task has next affiliate: " + prev);
4135                    sane = false;
4136                    break;
4137                }
4138            } else {
4139                // Verify middle of the chain's next points back to the one before.
4140                if (cur.mNextAffiliate != prev
4141                        || cur.mNextAffiliateTaskId != prev.taskId) {
4142                    Slog.wtf(TAG, "Bad chain @" + endIndex
4143                            + ": middle task " + cur + " @" + endIndex
4144                            + " has bad next affiliate "
4145                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4146                            + ", expected " + prev);
4147                    sane = false;
4148                    break;
4149                }
4150            }
4151            if (cur.mPrevAffiliateTaskId == -1) {
4152                // Chain ends here.
4153                if (cur.mPrevAffiliate != null) {
4154                    Slog.wtf(TAG, "Bad chain @" + endIndex
4155                            + ": last task " + cur + " has previous affiliate "
4156                            + cur.mPrevAffiliate);
4157                    sane = false;
4158                }
4159                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4160                break;
4161            } else {
4162                // Verify middle of the chain's prev points to a valid item.
4163                if (cur.mPrevAffiliate == null) {
4164                    Slog.wtf(TAG, "Bad chain @" + endIndex
4165                            + ": task " + cur + " has previous affiliate "
4166                            + cur.mPrevAffiliate + " but should be id "
4167                            + cur.mPrevAffiliate);
4168                    sane = false;
4169                    break;
4170                }
4171            }
4172            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4173                Slog.wtf(TAG, "Bad chain @" + endIndex
4174                        + ": task " + cur + " has affiliated id "
4175                        + cur.mAffiliatedTaskId + " but should be "
4176                        + task.mAffiliatedTaskId);
4177                sane = false;
4178                break;
4179            }
4180            prev = cur;
4181            endIndex++;
4182            if (endIndex >= N) {
4183                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4184                        + ": last task " + prev);
4185                sane = false;
4186                break;
4187            }
4188        }
4189        if (sane) {
4190            if (endIndex < taskIndex) {
4191                Slog.wtf(TAG, "Bad chain @" + endIndex
4192                        + ": did not extend to task " + task + " @" + taskIndex);
4193                sane = false;
4194            }
4195        }
4196        if (sane) {
4197            // All looks good, we can just move all of the affiliated tasks
4198            // to the top.
4199            for (int i=topIndex; i<=endIndex; i++) {
4200                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4201                        + " from " + i + " to " + (i-topIndex));
4202                TaskRecord cur = mRecentTasks.remove(i);
4203                mRecentTasks.add(i-topIndex, cur);
4204            }
4205            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4206                    + " to " + endIndex);
4207            return true;
4208        }
4209
4210        // Whoops, couldn't do it.
4211        return false;
4212    }
4213
4214    final void addRecentTaskLocked(TaskRecord task) {
4215        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4216                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4217
4218        int N = mRecentTasks.size();
4219        // Quick case: check if the top-most recent task is the same.
4220        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4221            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4222            return;
4223        }
4224        // Another quick case: check if this is part of a set of affiliated
4225        // tasks that are at the top.
4226        if (isAffiliated && N > 0 && task.inRecents
4227                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4228            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4229                    + " at top when adding " + task);
4230            return;
4231        }
4232        // Another quick case: never add voice sessions.
4233        if (task.voiceSession != null) {
4234            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4235            return;
4236        }
4237
4238        boolean needAffiliationFix = false;
4239
4240        // Slightly less quick case: the task is already in recents, so all we need
4241        // to do is move it.
4242        if (task.inRecents) {
4243            int taskIndex = mRecentTasks.indexOf(task);
4244            if (taskIndex >= 0) {
4245                if (!isAffiliated) {
4246                    // Simple case: this is not an affiliated task, so we just move it to the front.
4247                    mRecentTasks.remove(taskIndex);
4248                    mRecentTasks.add(0, task);
4249                    notifyTaskPersisterLocked(task, false);
4250                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4251                            + " from " + taskIndex);
4252                    return;
4253                } else {
4254                    // More complicated: need to keep all affiliated tasks together.
4255                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4256                        // All went well.
4257                        return;
4258                    }
4259
4260                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4261                    // everything and then go through our general path of adding a new task.
4262                    needAffiliationFix = true;
4263                }
4264            } else {
4265                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4266                needAffiliationFix = true;
4267            }
4268        }
4269
4270        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4271        trimRecentsForTask(task, true);
4272
4273        N = mRecentTasks.size();
4274        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4275            final TaskRecord tr = mRecentTasks.remove(N - 1);
4276            tr.removedFromRecents(mTaskPersister);
4277            N--;
4278        }
4279        task.inRecents = true;
4280        if (!isAffiliated || needAffiliationFix) {
4281            // If this is a simple non-affiliated task, or we had some failure trying to
4282            // handle it as part of an affilated task, then just place it at the top.
4283            mRecentTasks.add(0, task);
4284        } else if (isAffiliated) {
4285            // If this is a new affiliated task, then move all of the affiliated tasks
4286            // to the front and insert this new one.
4287            TaskRecord other = task.mNextAffiliate;
4288            if (other == null) {
4289                other = task.mPrevAffiliate;
4290            }
4291            if (other != null) {
4292                int otherIndex = mRecentTasks.indexOf(other);
4293                if (otherIndex >= 0) {
4294                    // Insert new task at appropriate location.
4295                    int taskIndex;
4296                    if (other == task.mNextAffiliate) {
4297                        // We found the index of our next affiliation, which is who is
4298                        // before us in the list, so add after that point.
4299                        taskIndex = otherIndex+1;
4300                    } else {
4301                        // We found the index of our previous affiliation, which is who is
4302                        // after us in the list, so add at their position.
4303                        taskIndex = otherIndex;
4304                    }
4305                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4306                            + taskIndex + ": " + task);
4307                    mRecentTasks.add(taskIndex, task);
4308
4309                    // Now move everything to the front.
4310                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4311                        // All went well.
4312                        return;
4313                    }
4314
4315                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4316                    // everything and then go through our general path of adding a new task.
4317                    needAffiliationFix = true;
4318                } else {
4319                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4320                            + other);
4321                    needAffiliationFix = true;
4322                }
4323            } else {
4324                if (DEBUG_RECENTS) Slog.d(TAG,
4325                        "addRecent: adding affiliated task without next/prev:" + task);
4326                needAffiliationFix = true;
4327            }
4328        }
4329        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4330
4331        if (needAffiliationFix) {
4332            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4333            cleanupRecentTasksLocked(task.userId);
4334        }
4335    }
4336
4337    /**
4338     * If needed, remove oldest existing entries in recents that are for the same kind
4339     * of task as the given one.
4340     */
4341    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4342        int N = mRecentTasks.size();
4343        final Intent intent = task.intent;
4344        final boolean document = intent != null && intent.isDocument();
4345
4346        int maxRecents = task.maxRecents - 1;
4347        for (int i=0; i<N; i++) {
4348            final TaskRecord tr = mRecentTasks.get(i);
4349            if (task != tr) {
4350                if (task.userId != tr.userId) {
4351                    continue;
4352                }
4353                if (i > MAX_RECENT_BITMAPS) {
4354                    tr.freeLastThumbnail();
4355                }
4356                final Intent trIntent = tr.intent;
4357                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4358                    (intent == null || !intent.filterEquals(trIntent))) {
4359                    continue;
4360                }
4361                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4362                if (document && trIsDocument) {
4363                    // These are the same document activity (not necessarily the same doc).
4364                    if (maxRecents > 0) {
4365                        --maxRecents;
4366                        continue;
4367                    }
4368                    // Hit the maximum number of documents for this task. Fall through
4369                    // and remove this document from recents.
4370                } else if (document || trIsDocument) {
4371                    // Only one of these is a document. Not the droid we're looking for.
4372                    continue;
4373                }
4374            }
4375
4376            if (!doTrim) {
4377                // If the caller is not actually asking for a trim, just tell them we reached
4378                // a point where the trim would happen.
4379                return i;
4380            }
4381
4382            // Either task and tr are the same or, their affinities match or their intents match
4383            // and neither of them is a document, or they are documents using the same activity
4384            // and their maxRecents has been reached.
4385            tr.disposeThumbnail();
4386            mRecentTasks.remove(i);
4387            if (task != tr) {
4388                tr.removedFromRecents(mTaskPersister);
4389            }
4390            i--;
4391            N--;
4392            if (task.intent == null) {
4393                // If the new recent task we are adding is not fully
4394                // specified, then replace it with the existing recent task.
4395                task = tr;
4396            }
4397            notifyTaskPersisterLocked(tr, false);
4398        }
4399
4400        return -1;
4401    }
4402
4403    @Override
4404    public void reportActivityFullyDrawn(IBinder token) {
4405        synchronized (this) {
4406            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4407            if (r == null) {
4408                return;
4409            }
4410            r.reportFullyDrawnLocked();
4411        }
4412    }
4413
4414    @Override
4415    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4416        synchronized (this) {
4417            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4418            if (r == null) {
4419                return;
4420            }
4421            final long origId = Binder.clearCallingIdentity();
4422            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4423            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4424                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4425            if (config != null) {
4426                r.frozenBeforeDestroy = true;
4427                if (!updateConfigurationLocked(config, r, false, false)) {
4428                    mStackSupervisor.resumeTopActivitiesLocked();
4429                }
4430            }
4431            Binder.restoreCallingIdentity(origId);
4432        }
4433    }
4434
4435    @Override
4436    public int getRequestedOrientation(IBinder token) {
4437        synchronized (this) {
4438            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4439            if (r == null) {
4440                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4441            }
4442            return mWindowManager.getAppOrientation(r.appToken);
4443        }
4444    }
4445
4446    /**
4447     * This is the internal entry point for handling Activity.finish().
4448     *
4449     * @param token The Binder token referencing the Activity we want to finish.
4450     * @param resultCode Result code, if any, from this Activity.
4451     * @param resultData Result data (Intent), if any, from this Activity.
4452     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4453     *            the root Activity in the task.
4454     *
4455     * @return Returns true if the activity successfully finished, or false if it is still running.
4456     */
4457    @Override
4458    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4459            boolean finishTask) {
4460        // Refuse possible leaked file descriptors
4461        if (resultData != null && resultData.hasFileDescriptors() == true) {
4462            throw new IllegalArgumentException("File descriptors passed in Intent");
4463        }
4464
4465        synchronized(this) {
4466            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4467            if (r == null) {
4468                return true;
4469            }
4470            // Keep track of the root activity of the task before we finish it
4471            TaskRecord tr = r.task;
4472            ActivityRecord rootR = tr.getRootActivity();
4473            // Do not allow task to finish in Lock Task mode.
4474            if (tr == mStackSupervisor.mLockTaskModeTask) {
4475                if (rootR == r) {
4476                    mStackSupervisor.showLockTaskToast();
4477                    return false;
4478                }
4479            }
4480            if (mController != null) {
4481                // Find the first activity that is not finishing.
4482                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4483                if (next != null) {
4484                    // ask watcher if this is allowed
4485                    boolean resumeOK = true;
4486                    try {
4487                        resumeOK = mController.activityResuming(next.packageName);
4488                    } catch (RemoteException e) {
4489                        mController = null;
4490                        Watchdog.getInstance().setActivityController(null);
4491                    }
4492
4493                    if (!resumeOK) {
4494                        return false;
4495                    }
4496                }
4497            }
4498            final long origId = Binder.clearCallingIdentity();
4499            try {
4500                boolean res;
4501                if (finishTask && r == rootR) {
4502                    // If requested, remove the task that is associated to this activity only if it
4503                    // was the root activity in the task.  The result code and data is ignored because
4504                    // we don't support returning them across task boundaries.
4505                    res = removeTaskByIdLocked(tr.taskId, 0);
4506                } else {
4507                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4508                            resultData, "app-request", true);
4509                }
4510                return res;
4511            } finally {
4512                Binder.restoreCallingIdentity(origId);
4513            }
4514        }
4515    }
4516
4517    @Override
4518    public final void finishHeavyWeightApp() {
4519        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4520                != PackageManager.PERMISSION_GRANTED) {
4521            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4522                    + Binder.getCallingPid()
4523                    + ", uid=" + Binder.getCallingUid()
4524                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4525            Slog.w(TAG, msg);
4526            throw new SecurityException(msg);
4527        }
4528
4529        synchronized(this) {
4530            if (mHeavyWeightProcess == null) {
4531                return;
4532            }
4533
4534            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4535                    mHeavyWeightProcess.activities);
4536            for (int i=0; i<activities.size(); i++) {
4537                ActivityRecord r = activities.get(i);
4538                if (!r.finishing) {
4539                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4540                            null, "finish-heavy", true);
4541                }
4542            }
4543
4544            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4545                    mHeavyWeightProcess.userId, 0));
4546            mHeavyWeightProcess = null;
4547        }
4548    }
4549
4550    @Override
4551    public void crashApplication(int uid, int initialPid, String packageName,
4552            String message) {
4553        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4554                != PackageManager.PERMISSION_GRANTED) {
4555            String msg = "Permission Denial: crashApplication() from pid="
4556                    + Binder.getCallingPid()
4557                    + ", uid=" + Binder.getCallingUid()
4558                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4559            Slog.w(TAG, msg);
4560            throw new SecurityException(msg);
4561        }
4562
4563        synchronized(this) {
4564            ProcessRecord proc = null;
4565
4566            // Figure out which process to kill.  We don't trust that initialPid
4567            // still has any relation to current pids, so must scan through the
4568            // list.
4569            synchronized (mPidsSelfLocked) {
4570                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4571                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4572                    if (p.uid != uid) {
4573                        continue;
4574                    }
4575                    if (p.pid == initialPid) {
4576                        proc = p;
4577                        break;
4578                    }
4579                    if (p.pkgList.containsKey(packageName)) {
4580                        proc = p;
4581                    }
4582                }
4583            }
4584
4585            if (proc == null) {
4586                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4587                        + " initialPid=" + initialPid
4588                        + " packageName=" + packageName);
4589                return;
4590            }
4591
4592            if (proc.thread != null) {
4593                if (proc.pid == Process.myPid()) {
4594                    Log.w(TAG, "crashApplication: trying to crash self!");
4595                    return;
4596                }
4597                long ident = Binder.clearCallingIdentity();
4598                try {
4599                    proc.thread.scheduleCrash(message);
4600                } catch (RemoteException e) {
4601                }
4602                Binder.restoreCallingIdentity(ident);
4603            }
4604        }
4605    }
4606
4607    @Override
4608    public final void finishSubActivity(IBinder token, String resultWho,
4609            int requestCode) {
4610        synchronized(this) {
4611            final long origId = Binder.clearCallingIdentity();
4612            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4613            if (r != null) {
4614                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4615            }
4616            Binder.restoreCallingIdentity(origId);
4617        }
4618    }
4619
4620    @Override
4621    public boolean finishActivityAffinity(IBinder token) {
4622        synchronized(this) {
4623            final long origId = Binder.clearCallingIdentity();
4624            try {
4625                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4626
4627                ActivityRecord rootR = r.task.getRootActivity();
4628                // Do not allow task to finish in Lock Task mode.
4629                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4630                    if (rootR == r) {
4631                        mStackSupervisor.showLockTaskToast();
4632                        return false;
4633                    }
4634                }
4635                boolean res = false;
4636                if (r != null) {
4637                    res = r.task.stack.finishActivityAffinityLocked(r);
4638                }
4639                return res;
4640            } finally {
4641                Binder.restoreCallingIdentity(origId);
4642            }
4643        }
4644    }
4645
4646    @Override
4647    public void finishVoiceTask(IVoiceInteractionSession session) {
4648        synchronized(this) {
4649            final long origId = Binder.clearCallingIdentity();
4650            try {
4651                mStackSupervisor.finishVoiceTask(session);
4652            } finally {
4653                Binder.restoreCallingIdentity(origId);
4654            }
4655        }
4656
4657    }
4658
4659    @Override
4660    public boolean releaseActivityInstance(IBinder token) {
4661        synchronized(this) {
4662            final long origId = Binder.clearCallingIdentity();
4663            try {
4664                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4665                if (r.task == null || r.task.stack == null) {
4666                    return false;
4667                }
4668                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4669            } finally {
4670                Binder.restoreCallingIdentity(origId);
4671            }
4672        }
4673    }
4674
4675    @Override
4676    public void releaseSomeActivities(IApplicationThread appInt) {
4677        synchronized(this) {
4678            final long origId = Binder.clearCallingIdentity();
4679            try {
4680                ProcessRecord app = getRecordForAppLocked(appInt);
4681                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4682            } finally {
4683                Binder.restoreCallingIdentity(origId);
4684            }
4685        }
4686    }
4687
4688    @Override
4689    public boolean willActivityBeVisible(IBinder token) {
4690        synchronized(this) {
4691            ActivityStack stack = ActivityRecord.getStackLocked(token);
4692            if (stack != null) {
4693                return stack.willActivityBeVisibleLocked(token);
4694            }
4695            return false;
4696        }
4697    }
4698
4699    @Override
4700    public void overridePendingTransition(IBinder token, String packageName,
4701            int enterAnim, int exitAnim) {
4702        synchronized(this) {
4703            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4704            if (self == null) {
4705                return;
4706            }
4707
4708            final long origId = Binder.clearCallingIdentity();
4709
4710            if (self.state == ActivityState.RESUMED
4711                    || self.state == ActivityState.PAUSING) {
4712                mWindowManager.overridePendingAppTransition(packageName,
4713                        enterAnim, exitAnim, null);
4714            }
4715
4716            Binder.restoreCallingIdentity(origId);
4717        }
4718    }
4719
4720    /**
4721     * Main function for removing an existing process from the activity manager
4722     * as a result of that process going away.  Clears out all connections
4723     * to the process.
4724     */
4725    private final void handleAppDiedLocked(ProcessRecord app,
4726            boolean restarting, boolean allowRestart) {
4727        int pid = app.pid;
4728        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4729        if (!kept && !restarting) {
4730            removeLruProcessLocked(app);
4731            if (pid > 0) {
4732                ProcessList.remove(pid);
4733            }
4734        }
4735
4736        if (mProfileProc == app) {
4737            clearProfilerLocked();
4738        }
4739
4740        // Remove this application's activities from active lists.
4741        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4742
4743        app.activities.clear();
4744
4745        if (app.instrumentationClass != null) {
4746            Slog.w(TAG, "Crash of app " + app.processName
4747                  + " running instrumentation " + app.instrumentationClass);
4748            Bundle info = new Bundle();
4749            info.putString("shortMsg", "Process crashed.");
4750            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4751        }
4752
4753        if (!restarting) {
4754            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4755                // If there was nothing to resume, and we are not already
4756                // restarting this process, but there is a visible activity that
4757                // is hosted by the process...  then make sure all visible
4758                // activities are running, taking care of restarting this
4759                // process.
4760                if (hasVisibleActivities) {
4761                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4762                }
4763            }
4764        }
4765    }
4766
4767    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4768        IBinder threadBinder = thread.asBinder();
4769        // Find the application record.
4770        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4771            ProcessRecord rec = mLruProcesses.get(i);
4772            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4773                return i;
4774            }
4775        }
4776        return -1;
4777    }
4778
4779    final ProcessRecord getRecordForAppLocked(
4780            IApplicationThread thread) {
4781        if (thread == null) {
4782            return null;
4783        }
4784
4785        int appIndex = getLRURecordIndexForAppLocked(thread);
4786        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4787    }
4788
4789    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4790        // If there are no longer any background processes running,
4791        // and the app that died was not running instrumentation,
4792        // then tell everyone we are now low on memory.
4793        boolean haveBg = false;
4794        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4795            ProcessRecord rec = mLruProcesses.get(i);
4796            if (rec.thread != null
4797                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4798                haveBg = true;
4799                break;
4800            }
4801        }
4802
4803        if (!haveBg) {
4804            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4805            if (doReport) {
4806                long now = SystemClock.uptimeMillis();
4807                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4808                    doReport = false;
4809                } else {
4810                    mLastMemUsageReportTime = now;
4811                }
4812            }
4813            final ArrayList<ProcessMemInfo> memInfos
4814                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4815            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4816            long now = SystemClock.uptimeMillis();
4817            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4818                ProcessRecord rec = mLruProcesses.get(i);
4819                if (rec == dyingProc || rec.thread == null) {
4820                    continue;
4821                }
4822                if (doReport) {
4823                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4824                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4825                }
4826                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4827                    // The low memory report is overriding any current
4828                    // state for a GC request.  Make sure to do
4829                    // heavy/important/visible/foreground processes first.
4830                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4831                        rec.lastRequestedGc = 0;
4832                    } else {
4833                        rec.lastRequestedGc = rec.lastLowMemory;
4834                    }
4835                    rec.reportLowMemory = true;
4836                    rec.lastLowMemory = now;
4837                    mProcessesToGc.remove(rec);
4838                    addProcessToGcListLocked(rec);
4839                }
4840            }
4841            if (doReport) {
4842                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4843                mHandler.sendMessage(msg);
4844            }
4845            scheduleAppGcsLocked();
4846        }
4847    }
4848
4849    final void appDiedLocked(ProcessRecord app) {
4850       appDiedLocked(app, app.pid, app.thread);
4851    }
4852
4853    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4854        // First check if this ProcessRecord is actually active for the pid.
4855        synchronized (mPidsSelfLocked) {
4856            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4857            if (curProc != app) {
4858                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4859                return;
4860            }
4861        }
4862
4863        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4864        synchronized (stats) {
4865            stats.noteProcessDiedLocked(app.info.uid, pid);
4866        }
4867
4868        Process.killProcessQuiet(pid);
4869        Process.killProcessGroup(app.info.uid, pid);
4870        app.killed = true;
4871
4872        // Clean up already done if the process has been re-started.
4873        if (app.pid == pid && app.thread != null &&
4874                app.thread.asBinder() == thread.asBinder()) {
4875            boolean doLowMem = app.instrumentationClass == null;
4876            boolean doOomAdj = doLowMem;
4877            if (!app.killedByAm) {
4878                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4879                        + ") has died");
4880                mAllowLowerMemLevel = true;
4881            } else {
4882                // Note that we always want to do oom adj to update our state with the
4883                // new number of procs.
4884                mAllowLowerMemLevel = false;
4885                doLowMem = false;
4886            }
4887            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4888            if (DEBUG_CLEANUP) Slog.v(
4889                TAG, "Dying app: " + app + ", pid: " + pid
4890                + ", thread: " + thread.asBinder());
4891            handleAppDiedLocked(app, false, true);
4892
4893            if (doOomAdj) {
4894                updateOomAdjLocked();
4895            }
4896            if (doLowMem) {
4897                doLowMemReportIfNeededLocked(app);
4898            }
4899        } else if (app.pid != pid) {
4900            // A new process has already been started.
4901            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4902                    + ") has died and restarted (pid " + app.pid + ").");
4903            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4904        } else if (DEBUG_PROCESSES) {
4905            Slog.d(TAG, "Received spurious death notification for thread "
4906                    + thread.asBinder());
4907        }
4908    }
4909
4910    /**
4911     * If a stack trace dump file is configured, dump process stack traces.
4912     * @param clearTraces causes the dump file to be erased prior to the new
4913     *    traces being written, if true; when false, the new traces will be
4914     *    appended to any existing file content.
4915     * @param firstPids of dalvik VM processes to dump stack traces for first
4916     * @param lastPids of dalvik VM processes to dump stack traces for last
4917     * @param nativeProcs optional list of native process names to dump stack crawls
4918     * @return file containing stack traces, or null if no dump file is configured
4919     */
4920    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4921            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4922        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4923        if (tracesPath == null || tracesPath.length() == 0) {
4924            return null;
4925        }
4926
4927        File tracesFile = new File(tracesPath);
4928        try {
4929            File tracesDir = tracesFile.getParentFile();
4930            if (!tracesDir.exists()) {
4931                tracesDir.mkdirs();
4932                if (!SELinux.restorecon(tracesDir)) {
4933                    return null;
4934                }
4935            }
4936            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4937
4938            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4939            tracesFile.createNewFile();
4940            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4941        } catch (IOException e) {
4942            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4943            return null;
4944        }
4945
4946        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4947        return tracesFile;
4948    }
4949
4950    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4951            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4952        // Use a FileObserver to detect when traces finish writing.
4953        // The order of traces is considered important to maintain for legibility.
4954        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4955            @Override
4956            public synchronized void onEvent(int event, String path) { notify(); }
4957        };
4958
4959        try {
4960            observer.startWatching();
4961
4962            // First collect all of the stacks of the most important pids.
4963            if (firstPids != null) {
4964                try {
4965                    int num = firstPids.size();
4966                    for (int i = 0; i < num; i++) {
4967                        synchronized (observer) {
4968                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4969                            observer.wait(200);  // Wait for write-close, give up after 200msec
4970                        }
4971                    }
4972                } catch (InterruptedException e) {
4973                    Slog.wtf(TAG, e);
4974                }
4975            }
4976
4977            // Next collect the stacks of the native pids
4978            if (nativeProcs != null) {
4979                int[] pids = Process.getPidsForCommands(nativeProcs);
4980                if (pids != null) {
4981                    for (int pid : pids) {
4982                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4983                    }
4984                }
4985            }
4986
4987            // Lastly, measure CPU usage.
4988            if (processCpuTracker != null) {
4989                processCpuTracker.init();
4990                System.gc();
4991                processCpuTracker.update();
4992                try {
4993                    synchronized (processCpuTracker) {
4994                        processCpuTracker.wait(500); // measure over 1/2 second.
4995                    }
4996                } catch (InterruptedException e) {
4997                }
4998                processCpuTracker.update();
4999
5000                // We'll take the stack crawls of just the top apps using CPU.
5001                final int N = processCpuTracker.countWorkingStats();
5002                int numProcs = 0;
5003                for (int i=0; i<N && numProcs<5; i++) {
5004                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5005                    if (lastPids.indexOfKey(stats.pid) >= 0) {
5006                        numProcs++;
5007                        try {
5008                            synchronized (observer) {
5009                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5010                                observer.wait(200);  // Wait for write-close, give up after 200msec
5011                            }
5012                        } catch (InterruptedException e) {
5013                            Slog.wtf(TAG, e);
5014                        }
5015
5016                    }
5017                }
5018            }
5019        } finally {
5020            observer.stopWatching();
5021        }
5022    }
5023
5024    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5025        if (true || IS_USER_BUILD) {
5026            return;
5027        }
5028        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5029        if (tracesPath == null || tracesPath.length() == 0) {
5030            return;
5031        }
5032
5033        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5034        StrictMode.allowThreadDiskWrites();
5035        try {
5036            final File tracesFile = new File(tracesPath);
5037            final File tracesDir = tracesFile.getParentFile();
5038            final File tracesTmp = new File(tracesDir, "__tmp__");
5039            try {
5040                if (!tracesDir.exists()) {
5041                    tracesDir.mkdirs();
5042                    if (!SELinux.restorecon(tracesDir.getPath())) {
5043                        return;
5044                    }
5045                }
5046                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5047
5048                if (tracesFile.exists()) {
5049                    tracesTmp.delete();
5050                    tracesFile.renameTo(tracesTmp);
5051                }
5052                StringBuilder sb = new StringBuilder();
5053                Time tobj = new Time();
5054                tobj.set(System.currentTimeMillis());
5055                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5056                sb.append(": ");
5057                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5058                sb.append(" since ");
5059                sb.append(msg);
5060                FileOutputStream fos = new FileOutputStream(tracesFile);
5061                fos.write(sb.toString().getBytes());
5062                if (app == null) {
5063                    fos.write("\n*** No application process!".getBytes());
5064                }
5065                fos.close();
5066                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5067            } catch (IOException e) {
5068                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5069                return;
5070            }
5071
5072            if (app != null) {
5073                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5074                firstPids.add(app.pid);
5075                dumpStackTraces(tracesPath, firstPids, null, null, null);
5076            }
5077
5078            File lastTracesFile = null;
5079            File curTracesFile = null;
5080            for (int i=9; i>=0; i--) {
5081                String name = String.format(Locale.US, "slow%02d.txt", i);
5082                curTracesFile = new File(tracesDir, name);
5083                if (curTracesFile.exists()) {
5084                    if (lastTracesFile != null) {
5085                        curTracesFile.renameTo(lastTracesFile);
5086                    } else {
5087                        curTracesFile.delete();
5088                    }
5089                }
5090                lastTracesFile = curTracesFile;
5091            }
5092            tracesFile.renameTo(curTracesFile);
5093            if (tracesTmp.exists()) {
5094                tracesTmp.renameTo(tracesFile);
5095            }
5096        } finally {
5097            StrictMode.setThreadPolicy(oldPolicy);
5098        }
5099    }
5100
5101    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5102            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5103        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5104        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5105
5106        if (mController != null) {
5107            try {
5108                // 0 == continue, -1 = kill process immediately
5109                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5110                if (res < 0 && app.pid != MY_PID) {
5111                    app.kill("anr", true);
5112                }
5113            } catch (RemoteException e) {
5114                mController = null;
5115                Watchdog.getInstance().setActivityController(null);
5116            }
5117        }
5118
5119        long anrTime = SystemClock.uptimeMillis();
5120        if (MONITOR_CPU_USAGE) {
5121            updateCpuStatsNow();
5122        }
5123
5124        synchronized (this) {
5125            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5126            if (mShuttingDown) {
5127                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5128                return;
5129            } else if (app.notResponding) {
5130                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5131                return;
5132            } else if (app.crashing) {
5133                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5134                return;
5135            }
5136
5137            // In case we come through here for the same app before completing
5138            // this one, mark as anring now so we will bail out.
5139            app.notResponding = true;
5140
5141            // Log the ANR to the event log.
5142            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5143                    app.processName, app.info.flags, annotation);
5144
5145            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5146            firstPids.add(app.pid);
5147
5148            int parentPid = app.pid;
5149            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5150            if (parentPid != app.pid) firstPids.add(parentPid);
5151
5152            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5153
5154            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5155                ProcessRecord r = mLruProcesses.get(i);
5156                if (r != null && r.thread != null) {
5157                    int pid = r.pid;
5158                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5159                        if (r.persistent) {
5160                            firstPids.add(pid);
5161                        } else {
5162                            lastPids.put(pid, Boolean.TRUE);
5163                        }
5164                    }
5165                }
5166            }
5167        }
5168
5169        // Log the ANR to the main log.
5170        StringBuilder info = new StringBuilder();
5171        info.setLength(0);
5172        info.append("ANR in ").append(app.processName);
5173        if (activity != null && activity.shortComponentName != null) {
5174            info.append(" (").append(activity.shortComponentName).append(")");
5175        }
5176        info.append("\n");
5177        info.append("PID: ").append(app.pid).append("\n");
5178        if (annotation != null) {
5179            info.append("Reason: ").append(annotation).append("\n");
5180        }
5181        if (parent != null && parent != activity) {
5182            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5183        }
5184
5185        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5186
5187        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5188                NATIVE_STACKS_OF_INTEREST);
5189
5190        String cpuInfo = null;
5191        if (MONITOR_CPU_USAGE) {
5192            updateCpuStatsNow();
5193            synchronized (mProcessCpuTracker) {
5194                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5195            }
5196            info.append(processCpuTracker.printCurrentLoad());
5197            info.append(cpuInfo);
5198        }
5199
5200        info.append(processCpuTracker.printCurrentState(anrTime));
5201
5202        Slog.e(TAG, info.toString());
5203        if (tracesFile == null) {
5204            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5205            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5206        }
5207
5208        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5209                cpuInfo, tracesFile, null);
5210
5211        if (mController != null) {
5212            try {
5213                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5214                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5215                if (res != 0) {
5216                    if (res < 0 && app.pid != MY_PID) {
5217                        app.kill("anr", true);
5218                    } else {
5219                        synchronized (this) {
5220                            mServices.scheduleServiceTimeoutLocked(app);
5221                        }
5222                    }
5223                    return;
5224                }
5225            } catch (RemoteException e) {
5226                mController = null;
5227                Watchdog.getInstance().setActivityController(null);
5228            }
5229        }
5230
5231        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5232        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5233                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5234
5235        synchronized (this) {
5236            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5237                app.kill("bg anr", true);
5238                return;
5239            }
5240
5241            // Set the app's notResponding state, and look up the errorReportReceiver
5242            makeAppNotRespondingLocked(app,
5243                    activity != null ? activity.shortComponentName : null,
5244                    annotation != null ? "ANR " + annotation : "ANR",
5245                    info.toString());
5246
5247            // Bring up the infamous App Not Responding dialog
5248            Message msg = Message.obtain();
5249            HashMap<String, Object> map = new HashMap<String, Object>();
5250            msg.what = SHOW_NOT_RESPONDING_MSG;
5251            msg.obj = map;
5252            msg.arg1 = aboveSystem ? 1 : 0;
5253            map.put("app", app);
5254            if (activity != null) {
5255                map.put("activity", activity);
5256            }
5257
5258            mHandler.sendMessage(msg);
5259        }
5260    }
5261
5262    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5263        if (!mLaunchWarningShown) {
5264            mLaunchWarningShown = true;
5265            mHandler.post(new Runnable() {
5266                @Override
5267                public void run() {
5268                    synchronized (ActivityManagerService.this) {
5269                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5270                        d.show();
5271                        mHandler.postDelayed(new Runnable() {
5272                            @Override
5273                            public void run() {
5274                                synchronized (ActivityManagerService.this) {
5275                                    d.dismiss();
5276                                    mLaunchWarningShown = false;
5277                                }
5278                            }
5279                        }, 4000);
5280                    }
5281                }
5282            });
5283        }
5284    }
5285
5286    @Override
5287    public boolean clearApplicationUserData(final String packageName,
5288            final IPackageDataObserver observer, int userId) {
5289        enforceNotIsolatedCaller("clearApplicationUserData");
5290        int uid = Binder.getCallingUid();
5291        int pid = Binder.getCallingPid();
5292        userId = handleIncomingUser(pid, uid,
5293                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5294        long callingId = Binder.clearCallingIdentity();
5295        try {
5296            IPackageManager pm = AppGlobals.getPackageManager();
5297            int pkgUid = -1;
5298            synchronized(this) {
5299                try {
5300                    pkgUid = pm.getPackageUid(packageName, userId);
5301                } catch (RemoteException e) {
5302                }
5303                if (pkgUid == -1) {
5304                    Slog.w(TAG, "Invalid packageName: " + packageName);
5305                    if (observer != null) {
5306                        try {
5307                            observer.onRemoveCompleted(packageName, false);
5308                        } catch (RemoteException e) {
5309                            Slog.i(TAG, "Observer no longer exists.");
5310                        }
5311                    }
5312                    return false;
5313                }
5314                if (uid == pkgUid || checkComponentPermission(
5315                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5316                        pid, uid, -1, true)
5317                        == PackageManager.PERMISSION_GRANTED) {
5318                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5319                } else {
5320                    throw new SecurityException("PID " + pid + " does not have permission "
5321                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5322                                    + " of package " + packageName);
5323                }
5324
5325                // Remove all tasks match the cleared application package and user
5326                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5327                    final TaskRecord tr = mRecentTasks.get(i);
5328                    final String taskPackageName =
5329                            tr.getBaseIntent().getComponent().getPackageName();
5330                    if (tr.userId != userId) continue;
5331                    if (!taskPackageName.equals(packageName)) continue;
5332                    removeTaskByIdLocked(tr.taskId, 0);
5333                }
5334            }
5335
5336            try {
5337                // Clear application user data
5338                pm.clearApplicationUserData(packageName, observer, userId);
5339
5340                synchronized(this) {
5341                    // Remove all permissions granted from/to this package
5342                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5343                }
5344
5345                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5346                        Uri.fromParts("package", packageName, null));
5347                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5348                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5349                        null, null, 0, null, null, null, false, false, userId);
5350            } catch (RemoteException e) {
5351            }
5352        } finally {
5353            Binder.restoreCallingIdentity(callingId);
5354        }
5355        return true;
5356    }
5357
5358    @Override
5359    public void killBackgroundProcesses(final String packageName, int userId) {
5360        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5361                != PackageManager.PERMISSION_GRANTED &&
5362                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5363                        != PackageManager.PERMISSION_GRANTED) {
5364            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5365                    + Binder.getCallingPid()
5366                    + ", uid=" + Binder.getCallingUid()
5367                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5368            Slog.w(TAG, msg);
5369            throw new SecurityException(msg);
5370        }
5371
5372        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5373                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5374        long callingId = Binder.clearCallingIdentity();
5375        try {
5376            IPackageManager pm = AppGlobals.getPackageManager();
5377            synchronized(this) {
5378                int appId = -1;
5379                try {
5380                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5381                } catch (RemoteException e) {
5382                }
5383                if (appId == -1) {
5384                    Slog.w(TAG, "Invalid packageName: " + packageName);
5385                    return;
5386                }
5387                killPackageProcessesLocked(packageName, appId, userId,
5388                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5389            }
5390        } finally {
5391            Binder.restoreCallingIdentity(callingId);
5392        }
5393    }
5394
5395    @Override
5396    public void killAllBackgroundProcesses() {
5397        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5398                != PackageManager.PERMISSION_GRANTED) {
5399            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5400                    + Binder.getCallingPid()
5401                    + ", uid=" + Binder.getCallingUid()
5402                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5403            Slog.w(TAG, msg);
5404            throw new SecurityException(msg);
5405        }
5406
5407        long callingId = Binder.clearCallingIdentity();
5408        try {
5409            synchronized(this) {
5410                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5411                final int NP = mProcessNames.getMap().size();
5412                for (int ip=0; ip<NP; ip++) {
5413                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5414                    final int NA = apps.size();
5415                    for (int ia=0; ia<NA; ia++) {
5416                        ProcessRecord app = apps.valueAt(ia);
5417                        if (app.persistent) {
5418                            // we don't kill persistent processes
5419                            continue;
5420                        }
5421                        if (app.removed) {
5422                            procs.add(app);
5423                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5424                            app.removed = true;
5425                            procs.add(app);
5426                        }
5427                    }
5428                }
5429
5430                int N = procs.size();
5431                for (int i=0; i<N; i++) {
5432                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5433                }
5434                mAllowLowerMemLevel = true;
5435                updateOomAdjLocked();
5436                doLowMemReportIfNeededLocked(null);
5437            }
5438        } finally {
5439            Binder.restoreCallingIdentity(callingId);
5440        }
5441    }
5442
5443    @Override
5444    public void forceStopPackage(final String packageName, int userId) {
5445        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5446                != PackageManager.PERMISSION_GRANTED) {
5447            String msg = "Permission Denial: forceStopPackage() from pid="
5448                    + Binder.getCallingPid()
5449                    + ", uid=" + Binder.getCallingUid()
5450                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5451            Slog.w(TAG, msg);
5452            throw new SecurityException(msg);
5453        }
5454        final int callingPid = Binder.getCallingPid();
5455        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5456                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5457        long callingId = Binder.clearCallingIdentity();
5458        try {
5459            IPackageManager pm = AppGlobals.getPackageManager();
5460            synchronized(this) {
5461                int[] users = userId == UserHandle.USER_ALL
5462                        ? getUsersLocked() : new int[] { userId };
5463                for (int user : users) {
5464                    int pkgUid = -1;
5465                    try {
5466                        pkgUid = pm.getPackageUid(packageName, user);
5467                    } catch (RemoteException e) {
5468                    }
5469                    if (pkgUid == -1) {
5470                        Slog.w(TAG, "Invalid packageName: " + packageName);
5471                        continue;
5472                    }
5473                    try {
5474                        pm.setPackageStoppedState(packageName, true, user);
5475                    } catch (RemoteException e) {
5476                    } catch (IllegalArgumentException e) {
5477                        Slog.w(TAG, "Failed trying to unstop package "
5478                                + packageName + ": " + e);
5479                    }
5480                    if (isUserRunningLocked(user, false)) {
5481                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5482                    }
5483                }
5484            }
5485        } finally {
5486            Binder.restoreCallingIdentity(callingId);
5487        }
5488    }
5489
5490    @Override
5491    public void addPackageDependency(String packageName) {
5492        synchronized (this) {
5493            int callingPid = Binder.getCallingPid();
5494            if (callingPid == Process.myPid()) {
5495                //  Yeah, um, no.
5496                Slog.w(TAG, "Can't addPackageDependency on system process");
5497                return;
5498            }
5499            ProcessRecord proc;
5500            synchronized (mPidsSelfLocked) {
5501                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5502            }
5503            if (proc != null) {
5504                if (proc.pkgDeps == null) {
5505                    proc.pkgDeps = new ArraySet<String>(1);
5506                }
5507                proc.pkgDeps.add(packageName);
5508            }
5509        }
5510    }
5511
5512    /*
5513     * The pkg name and app id have to be specified.
5514     */
5515    @Override
5516    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5517        if (pkg == null) {
5518            return;
5519        }
5520        // Make sure the uid is valid.
5521        if (appid < 0) {
5522            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5523            return;
5524        }
5525        int callerUid = Binder.getCallingUid();
5526        // Only the system server can kill an application
5527        if (callerUid == Process.SYSTEM_UID) {
5528            // Post an aysnc message to kill the application
5529            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5530            msg.arg1 = appid;
5531            msg.arg2 = 0;
5532            Bundle bundle = new Bundle();
5533            bundle.putString("pkg", pkg);
5534            bundle.putString("reason", reason);
5535            msg.obj = bundle;
5536            mHandler.sendMessage(msg);
5537        } else {
5538            throw new SecurityException(callerUid + " cannot kill pkg: " +
5539                    pkg);
5540        }
5541    }
5542
5543    @Override
5544    public void closeSystemDialogs(String reason) {
5545        enforceNotIsolatedCaller("closeSystemDialogs");
5546
5547        final int pid = Binder.getCallingPid();
5548        final int uid = Binder.getCallingUid();
5549        final long origId = Binder.clearCallingIdentity();
5550        try {
5551            synchronized (this) {
5552                // Only allow this from foreground processes, so that background
5553                // applications can't abuse it to prevent system UI from being shown.
5554                if (uid >= Process.FIRST_APPLICATION_UID) {
5555                    ProcessRecord proc;
5556                    synchronized (mPidsSelfLocked) {
5557                        proc = mPidsSelfLocked.get(pid);
5558                    }
5559                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5560                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5561                                + " from background process " + proc);
5562                        return;
5563                    }
5564                }
5565                closeSystemDialogsLocked(reason);
5566            }
5567        } finally {
5568            Binder.restoreCallingIdentity(origId);
5569        }
5570    }
5571
5572    void closeSystemDialogsLocked(String reason) {
5573        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5574        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5575                | Intent.FLAG_RECEIVER_FOREGROUND);
5576        if (reason != null) {
5577            intent.putExtra("reason", reason);
5578        }
5579        mWindowManager.closeSystemDialogs(reason);
5580
5581        mStackSupervisor.closeSystemDialogsLocked();
5582
5583        broadcastIntentLocked(null, null, intent, null,
5584                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5585                Process.SYSTEM_UID, UserHandle.USER_ALL);
5586    }
5587
5588    @Override
5589    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5590        enforceNotIsolatedCaller("getProcessMemoryInfo");
5591        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5592        for (int i=pids.length-1; i>=0; i--) {
5593            ProcessRecord proc;
5594            int oomAdj;
5595            synchronized (this) {
5596                synchronized (mPidsSelfLocked) {
5597                    proc = mPidsSelfLocked.get(pids[i]);
5598                    oomAdj = proc != null ? proc.setAdj : 0;
5599                }
5600            }
5601            infos[i] = new Debug.MemoryInfo();
5602            Debug.getMemoryInfo(pids[i], infos[i]);
5603            if (proc != null) {
5604                synchronized (this) {
5605                    if (proc.thread != null && proc.setAdj == oomAdj) {
5606                        // Record this for posterity if the process has been stable.
5607                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5608                                infos[i].getTotalUss(), false, proc.pkgList);
5609                    }
5610                }
5611            }
5612        }
5613        return infos;
5614    }
5615
5616    @Override
5617    public long[] getProcessPss(int[] pids) {
5618        enforceNotIsolatedCaller("getProcessPss");
5619        long[] pss = new long[pids.length];
5620        for (int i=pids.length-1; i>=0; i--) {
5621            ProcessRecord proc;
5622            int oomAdj;
5623            synchronized (this) {
5624                synchronized (mPidsSelfLocked) {
5625                    proc = mPidsSelfLocked.get(pids[i]);
5626                    oomAdj = proc != null ? proc.setAdj : 0;
5627                }
5628            }
5629            long[] tmpUss = new long[1];
5630            pss[i] = Debug.getPss(pids[i], tmpUss);
5631            if (proc != null) {
5632                synchronized (this) {
5633                    if (proc.thread != null && proc.setAdj == oomAdj) {
5634                        // Record this for posterity if the process has been stable.
5635                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5636                    }
5637                }
5638            }
5639        }
5640        return pss;
5641    }
5642
5643    @Override
5644    public void killApplicationProcess(String processName, int uid) {
5645        if (processName == null) {
5646            return;
5647        }
5648
5649        int callerUid = Binder.getCallingUid();
5650        // Only the system server can kill an application
5651        if (callerUid == Process.SYSTEM_UID) {
5652            synchronized (this) {
5653                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5654                if (app != null && app.thread != null) {
5655                    try {
5656                        app.thread.scheduleSuicide();
5657                    } catch (RemoteException e) {
5658                        // If the other end already died, then our work here is done.
5659                    }
5660                } else {
5661                    Slog.w(TAG, "Process/uid not found attempting kill of "
5662                            + processName + " / " + uid);
5663                }
5664            }
5665        } else {
5666            throw new SecurityException(callerUid + " cannot kill app process: " +
5667                    processName);
5668        }
5669    }
5670
5671    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5672        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5673                false, true, false, false, UserHandle.getUserId(uid), reason);
5674        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5675                Uri.fromParts("package", packageName, null));
5676        if (!mProcessesReady) {
5677            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5678                    | Intent.FLAG_RECEIVER_FOREGROUND);
5679        }
5680        intent.putExtra(Intent.EXTRA_UID, uid);
5681        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5682        broadcastIntentLocked(null, null, intent,
5683                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5684                false, false,
5685                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5686    }
5687
5688    private void forceStopUserLocked(int userId, String reason) {
5689        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5690        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5691        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5692                | Intent.FLAG_RECEIVER_FOREGROUND);
5693        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5694        broadcastIntentLocked(null, null, intent,
5695                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5696                false, false,
5697                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5698    }
5699
5700    private final boolean killPackageProcessesLocked(String packageName, int appId,
5701            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5702            boolean doit, boolean evenPersistent, String reason) {
5703        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5704
5705        // Remove all processes this package may have touched: all with the
5706        // same UID (except for the system or root user), and all whose name
5707        // matches the package name.
5708        final int NP = mProcessNames.getMap().size();
5709        for (int ip=0; ip<NP; ip++) {
5710            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5711            final int NA = apps.size();
5712            for (int ia=0; ia<NA; ia++) {
5713                ProcessRecord app = apps.valueAt(ia);
5714                if (app.persistent && !evenPersistent) {
5715                    // we don't kill persistent processes
5716                    continue;
5717                }
5718                if (app.removed) {
5719                    if (doit) {
5720                        procs.add(app);
5721                    }
5722                    continue;
5723                }
5724
5725                // Skip process if it doesn't meet our oom adj requirement.
5726                if (app.setAdj < minOomAdj) {
5727                    continue;
5728                }
5729
5730                // If no package is specified, we call all processes under the
5731                // give user id.
5732                if (packageName == null) {
5733                    if (app.userId != userId) {
5734                        continue;
5735                    }
5736                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5737                        continue;
5738                    }
5739                // Package has been specified, we want to hit all processes
5740                // that match it.  We need to qualify this by the processes
5741                // that are running under the specified app and user ID.
5742                } else {
5743                    final boolean isDep = app.pkgDeps != null
5744                            && app.pkgDeps.contains(packageName);
5745                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5746                        continue;
5747                    }
5748                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5749                        continue;
5750                    }
5751                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5752                        continue;
5753                    }
5754                }
5755
5756                // Process has passed all conditions, kill it!
5757                if (!doit) {
5758                    return true;
5759                }
5760                app.removed = true;
5761                procs.add(app);
5762            }
5763        }
5764
5765        int N = procs.size();
5766        for (int i=0; i<N; i++) {
5767            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5768        }
5769        updateOomAdjLocked();
5770        return N > 0;
5771    }
5772
5773    private final boolean forceStopPackageLocked(String name, int appId,
5774            boolean callerWillRestart, boolean purgeCache, boolean doit,
5775            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5776        int i;
5777        int N;
5778
5779        if (userId == UserHandle.USER_ALL && name == null) {
5780            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5781        }
5782
5783        if (appId < 0 && name != null) {
5784            try {
5785                appId = UserHandle.getAppId(
5786                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5787            } catch (RemoteException e) {
5788            }
5789        }
5790
5791        if (doit) {
5792            if (name != null) {
5793                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5794                        + " user=" + userId + ": " + reason);
5795            } else {
5796                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5797            }
5798
5799            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5800            for (int ip=pmap.size()-1; ip>=0; ip--) {
5801                SparseArray<Long> ba = pmap.valueAt(ip);
5802                for (i=ba.size()-1; i>=0; i--) {
5803                    boolean remove = false;
5804                    final int entUid = ba.keyAt(i);
5805                    if (name != null) {
5806                        if (userId == UserHandle.USER_ALL) {
5807                            if (UserHandle.getAppId(entUid) == appId) {
5808                                remove = true;
5809                            }
5810                        } else {
5811                            if (entUid == UserHandle.getUid(userId, appId)) {
5812                                remove = true;
5813                            }
5814                        }
5815                    } else if (UserHandle.getUserId(entUid) == userId) {
5816                        remove = true;
5817                    }
5818                    if (remove) {
5819                        ba.removeAt(i);
5820                    }
5821                }
5822                if (ba.size() == 0) {
5823                    pmap.removeAt(ip);
5824                }
5825            }
5826        }
5827
5828        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5829                -100, callerWillRestart, true, doit, evenPersistent,
5830                name == null ? ("stop user " + userId) : ("stop " + name));
5831
5832        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5833            if (!doit) {
5834                return true;
5835            }
5836            didSomething = true;
5837        }
5838
5839        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5840            if (!doit) {
5841                return true;
5842            }
5843            didSomething = true;
5844        }
5845
5846        if (name == null) {
5847            // Remove all sticky broadcasts from this user.
5848            mStickyBroadcasts.remove(userId);
5849        }
5850
5851        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5852        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5853                userId, providers)) {
5854            if (!doit) {
5855                return true;
5856            }
5857            didSomething = true;
5858        }
5859        N = providers.size();
5860        for (i=0; i<N; i++) {
5861            removeDyingProviderLocked(null, providers.get(i), true);
5862        }
5863
5864        // Remove transient permissions granted from/to this package/user
5865        removeUriPermissionsForPackageLocked(name, userId, false);
5866
5867        if (name == null || uninstalling) {
5868            // Remove pending intents.  For now we only do this when force
5869            // stopping users, because we have some problems when doing this
5870            // for packages -- app widgets are not currently cleaned up for
5871            // such packages, so they can be left with bad pending intents.
5872            if (mIntentSenderRecords.size() > 0) {
5873                Iterator<WeakReference<PendingIntentRecord>> it
5874                        = mIntentSenderRecords.values().iterator();
5875                while (it.hasNext()) {
5876                    WeakReference<PendingIntentRecord> wpir = it.next();
5877                    if (wpir == null) {
5878                        it.remove();
5879                        continue;
5880                    }
5881                    PendingIntentRecord pir = wpir.get();
5882                    if (pir == null) {
5883                        it.remove();
5884                        continue;
5885                    }
5886                    if (name == null) {
5887                        // Stopping user, remove all objects for the user.
5888                        if (pir.key.userId != userId) {
5889                            // Not the same user, skip it.
5890                            continue;
5891                        }
5892                    } else {
5893                        if (UserHandle.getAppId(pir.uid) != appId) {
5894                            // Different app id, skip it.
5895                            continue;
5896                        }
5897                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5898                            // Different user, skip it.
5899                            continue;
5900                        }
5901                        if (!pir.key.packageName.equals(name)) {
5902                            // Different package, skip it.
5903                            continue;
5904                        }
5905                    }
5906                    if (!doit) {
5907                        return true;
5908                    }
5909                    didSomething = true;
5910                    it.remove();
5911                    pir.canceled = true;
5912                    if (pir.key.activity != null) {
5913                        pir.key.activity.pendingResults.remove(pir.ref);
5914                    }
5915                }
5916            }
5917        }
5918
5919        if (doit) {
5920            if (purgeCache && name != null) {
5921                AttributeCache ac = AttributeCache.instance();
5922                if (ac != null) {
5923                    ac.removePackage(name);
5924                }
5925            }
5926            if (mBooted) {
5927                mStackSupervisor.resumeTopActivitiesLocked();
5928                mStackSupervisor.scheduleIdleLocked();
5929            }
5930        }
5931
5932        return didSomething;
5933    }
5934
5935    private final boolean removeProcessLocked(ProcessRecord app,
5936            boolean callerWillRestart, boolean allowRestart, String reason) {
5937        final String name = app.processName;
5938        final int uid = app.uid;
5939        if (DEBUG_PROCESSES) Slog.d(
5940            TAG, "Force removing proc " + app.toShortString() + " (" + name
5941            + "/" + uid + ")");
5942
5943        mProcessNames.remove(name, uid);
5944        mIsolatedProcesses.remove(app.uid);
5945        if (mHeavyWeightProcess == app) {
5946            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5947                    mHeavyWeightProcess.userId, 0));
5948            mHeavyWeightProcess = null;
5949        }
5950        boolean needRestart = false;
5951        if (app.pid > 0 && app.pid != MY_PID) {
5952            int pid = app.pid;
5953            synchronized (mPidsSelfLocked) {
5954                mPidsSelfLocked.remove(pid);
5955                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5956            }
5957            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5958            if (app.isolated) {
5959                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5960            }
5961            app.kill(reason, true);
5962            handleAppDiedLocked(app, true, allowRestart);
5963            removeLruProcessLocked(app);
5964
5965            if (app.persistent && !app.isolated) {
5966                if (!callerWillRestart) {
5967                    addAppLocked(app.info, false, null /* ABI override */);
5968                } else {
5969                    needRestart = true;
5970                }
5971            }
5972        } else {
5973            mRemovedProcesses.add(app);
5974        }
5975
5976        return needRestart;
5977    }
5978
5979    private final void processStartTimedOutLocked(ProcessRecord app) {
5980        final int pid = app.pid;
5981        boolean gone = false;
5982        synchronized (mPidsSelfLocked) {
5983            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5984            if (knownApp != null && knownApp.thread == null) {
5985                mPidsSelfLocked.remove(pid);
5986                gone = true;
5987            }
5988        }
5989
5990        if (gone) {
5991            Slog.w(TAG, "Process " + app + " failed to attach");
5992            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5993                    pid, app.uid, app.processName);
5994            mProcessNames.remove(app.processName, app.uid);
5995            mIsolatedProcesses.remove(app.uid);
5996            if (mHeavyWeightProcess == app) {
5997                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5998                        mHeavyWeightProcess.userId, 0));
5999                mHeavyWeightProcess = null;
6000            }
6001            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6002            if (app.isolated) {
6003                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6004            }
6005            // Take care of any launching providers waiting for this process.
6006            checkAppInLaunchingProvidersLocked(app, true);
6007            // Take care of any services that are waiting for the process.
6008            mServices.processStartTimedOutLocked(app);
6009            app.kill("start timeout", true);
6010            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6011                Slog.w(TAG, "Unattached app died before backup, skipping");
6012                try {
6013                    IBackupManager bm = IBackupManager.Stub.asInterface(
6014                            ServiceManager.getService(Context.BACKUP_SERVICE));
6015                    bm.agentDisconnected(app.info.packageName);
6016                } catch (RemoteException e) {
6017                    // Can't happen; the backup manager is local
6018                }
6019            }
6020            if (isPendingBroadcastProcessLocked(pid)) {
6021                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6022                skipPendingBroadcastLocked(pid);
6023            }
6024        } else {
6025            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6026        }
6027    }
6028
6029    private final boolean attachApplicationLocked(IApplicationThread thread,
6030            int pid) {
6031
6032        // Find the application record that is being attached...  either via
6033        // the pid if we are running in multiple processes, or just pull the
6034        // next app record if we are emulating process with anonymous threads.
6035        ProcessRecord app;
6036        if (pid != MY_PID && pid >= 0) {
6037            synchronized (mPidsSelfLocked) {
6038                app = mPidsSelfLocked.get(pid);
6039            }
6040        } else {
6041            app = null;
6042        }
6043
6044        if (app == null) {
6045            Slog.w(TAG, "No pending application record for pid " + pid
6046                    + " (IApplicationThread " + thread + "); dropping process");
6047            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6048            if (pid > 0 && pid != MY_PID) {
6049                Process.killProcessQuiet(pid);
6050                //TODO: Process.killProcessGroup(app.info.uid, pid);
6051            } else {
6052                try {
6053                    thread.scheduleExit();
6054                } catch (Exception e) {
6055                    // Ignore exceptions.
6056                }
6057            }
6058            return false;
6059        }
6060
6061        // If this application record is still attached to a previous
6062        // process, clean it up now.
6063        if (app.thread != null) {
6064            handleAppDiedLocked(app, true, true);
6065        }
6066
6067        // Tell the process all about itself.
6068
6069        if (localLOGV) Slog.v(
6070                TAG, "Binding process pid " + pid + " to record " + app);
6071
6072        final String processName = app.processName;
6073        try {
6074            AppDeathRecipient adr = new AppDeathRecipient(
6075                    app, pid, thread);
6076            thread.asBinder().linkToDeath(adr, 0);
6077            app.deathRecipient = adr;
6078        } catch (RemoteException e) {
6079            app.resetPackageList(mProcessStats);
6080            startProcessLocked(app, "link fail", processName);
6081            return false;
6082        }
6083
6084        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6085
6086        app.makeActive(thread, mProcessStats);
6087        app.curAdj = app.setAdj = -100;
6088        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6089        app.forcingToForeground = null;
6090        updateProcessForegroundLocked(app, false, false);
6091        app.hasShownUi = false;
6092        app.debugging = false;
6093        app.cached = false;
6094
6095        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6096
6097        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6098        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6099
6100        if (!normalMode) {
6101            Slog.i(TAG, "Launching preboot mode app: " + app);
6102        }
6103
6104        if (localLOGV) Slog.v(
6105            TAG, "New app record " + app
6106            + " thread=" + thread.asBinder() + " pid=" + pid);
6107        try {
6108            int testMode = IApplicationThread.DEBUG_OFF;
6109            if (mDebugApp != null && mDebugApp.equals(processName)) {
6110                testMode = mWaitForDebugger
6111                    ? IApplicationThread.DEBUG_WAIT
6112                    : IApplicationThread.DEBUG_ON;
6113                app.debugging = true;
6114                if (mDebugTransient) {
6115                    mDebugApp = mOrigDebugApp;
6116                    mWaitForDebugger = mOrigWaitForDebugger;
6117                }
6118            }
6119            String profileFile = app.instrumentationProfileFile;
6120            ParcelFileDescriptor profileFd = null;
6121            int samplingInterval = 0;
6122            boolean profileAutoStop = false;
6123            if (mProfileApp != null && mProfileApp.equals(processName)) {
6124                mProfileProc = app;
6125                profileFile = mProfileFile;
6126                profileFd = mProfileFd;
6127                samplingInterval = mSamplingInterval;
6128                profileAutoStop = mAutoStopProfiler;
6129            }
6130            boolean enableOpenGlTrace = false;
6131            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6132                enableOpenGlTrace = true;
6133                mOpenGlTraceApp = null;
6134            }
6135
6136            // If the app is being launched for restore or full backup, set it up specially
6137            boolean isRestrictedBackupMode = false;
6138            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6139                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6140                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6141                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6142            }
6143
6144            ensurePackageDexOpt(app.instrumentationInfo != null
6145                    ? app.instrumentationInfo.packageName
6146                    : app.info.packageName);
6147            if (app.instrumentationClass != null) {
6148                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6149            }
6150            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6151                    + processName + " with config " + mConfiguration);
6152            ApplicationInfo appInfo = app.instrumentationInfo != null
6153                    ? app.instrumentationInfo : app.info;
6154            app.compat = compatibilityInfoForPackageLocked(appInfo);
6155            if (profileFd != null) {
6156                profileFd = profileFd.dup();
6157            }
6158            ProfilerInfo profilerInfo = profileFile == null ? null
6159                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6160            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6161                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6162                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6163                    isRestrictedBackupMode || !normalMode, app.persistent,
6164                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6165                    mCoreSettingsObserver.getCoreSettingsLocked());
6166            updateLruProcessLocked(app, false, null);
6167            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6168        } catch (Exception e) {
6169            // todo: Yikes!  What should we do?  For now we will try to
6170            // start another process, but that could easily get us in
6171            // an infinite loop of restarting processes...
6172            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6173
6174            app.resetPackageList(mProcessStats);
6175            app.unlinkDeathRecipient();
6176            startProcessLocked(app, "bind fail", processName);
6177            return false;
6178        }
6179
6180        // Remove this record from the list of starting applications.
6181        mPersistentStartingProcesses.remove(app);
6182        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6183                "Attach application locked removing on hold: " + app);
6184        mProcessesOnHold.remove(app);
6185
6186        boolean badApp = false;
6187        boolean didSomething = false;
6188
6189        // See if the top visible activity is waiting to run in this process...
6190        if (normalMode) {
6191            try {
6192                if (mStackSupervisor.attachApplicationLocked(app)) {
6193                    didSomething = true;
6194                }
6195            } catch (Exception e) {
6196                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6197                badApp = true;
6198            }
6199        }
6200
6201        // Find any services that should be running in this process...
6202        if (!badApp) {
6203            try {
6204                didSomething |= mServices.attachApplicationLocked(app, processName);
6205            } catch (Exception e) {
6206                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6207                badApp = true;
6208            }
6209        }
6210
6211        // Check if a next-broadcast receiver is in this process...
6212        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6213            try {
6214                didSomething |= sendPendingBroadcastsLocked(app);
6215            } catch (Exception e) {
6216                // If the app died trying to launch the receiver we declare it 'bad'
6217                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6218                badApp = true;
6219            }
6220        }
6221
6222        // Check whether the next backup agent is in this process...
6223        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6224            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6225            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6226            try {
6227                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6228                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6229                        mBackupTarget.backupMode);
6230            } catch (Exception e) {
6231                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6232                badApp = true;
6233            }
6234        }
6235
6236        if (badApp) {
6237            app.kill("error during init", true);
6238            handleAppDiedLocked(app, false, true);
6239            return false;
6240        }
6241
6242        if (!didSomething) {
6243            updateOomAdjLocked();
6244        }
6245
6246        return true;
6247    }
6248
6249    @Override
6250    public final void attachApplication(IApplicationThread thread) {
6251        synchronized (this) {
6252            int callingPid = Binder.getCallingPid();
6253            final long origId = Binder.clearCallingIdentity();
6254            attachApplicationLocked(thread, callingPid);
6255            Binder.restoreCallingIdentity(origId);
6256        }
6257    }
6258
6259    @Override
6260    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6261        final long origId = Binder.clearCallingIdentity();
6262        synchronized (this) {
6263            ActivityStack stack = ActivityRecord.getStackLocked(token);
6264            if (stack != null) {
6265                ActivityRecord r =
6266                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6267                if (stopProfiling) {
6268                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6269                        try {
6270                            mProfileFd.close();
6271                        } catch (IOException e) {
6272                        }
6273                        clearProfilerLocked();
6274                    }
6275                }
6276            }
6277        }
6278        Binder.restoreCallingIdentity(origId);
6279    }
6280
6281    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6282        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6283                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6284    }
6285
6286    void enableScreenAfterBoot() {
6287        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6288                SystemClock.uptimeMillis());
6289        mWindowManager.enableScreenAfterBoot();
6290
6291        synchronized (this) {
6292            updateEventDispatchingLocked();
6293        }
6294    }
6295
6296    @Override
6297    public void showBootMessage(final CharSequence msg, final boolean always) {
6298        enforceNotIsolatedCaller("showBootMessage");
6299        mWindowManager.showBootMessage(msg, always);
6300    }
6301
6302    @Override
6303    public void keyguardWaitingForActivityDrawn() {
6304        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6305        final long token = Binder.clearCallingIdentity();
6306        try {
6307            synchronized (this) {
6308                if (DEBUG_LOCKSCREEN) logLockScreen("");
6309                mWindowManager.keyguardWaitingForActivityDrawn();
6310                if (mLockScreenShown) {
6311                    mLockScreenShown = false;
6312                    comeOutOfSleepIfNeededLocked();
6313                }
6314            }
6315        } finally {
6316            Binder.restoreCallingIdentity(token);
6317        }
6318    }
6319
6320    final void finishBooting() {
6321        synchronized (this) {
6322            if (!mBootAnimationComplete) {
6323                mCallFinishBooting = true;
6324                return;
6325            }
6326            mCallFinishBooting = false;
6327        }
6328
6329        // Register receivers to handle package update events
6330        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6331
6332        // Let system services know.
6333        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6334
6335        synchronized (this) {
6336            // Ensure that any processes we had put on hold are now started
6337            // up.
6338            final int NP = mProcessesOnHold.size();
6339            if (NP > 0) {
6340                ArrayList<ProcessRecord> procs =
6341                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6342                for (int ip=0; ip<NP; ip++) {
6343                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6344                            + procs.get(ip));
6345                    startProcessLocked(procs.get(ip), "on-hold", null);
6346                }
6347            }
6348
6349            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6350                // Start looking for apps that are abusing wake locks.
6351                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6352                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6353                // Tell anyone interested that we are done booting!
6354                SystemProperties.set("sys.boot_completed", "1");
6355
6356                // And trigger dev.bootcomplete if we are not showing encryption progress
6357                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6358                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6359                    SystemProperties.set("dev.bootcomplete", "1");
6360                }
6361                for (int i=0; i<mStartedUsers.size(); i++) {
6362                    UserStartedState uss = mStartedUsers.valueAt(i);
6363                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6364                        uss.mState = UserStartedState.STATE_RUNNING;
6365                        final int userId = mStartedUsers.keyAt(i);
6366                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6367                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6368                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6369                        broadcastIntentLocked(null, null, intent, null,
6370                                new IIntentReceiver.Stub() {
6371                                    @Override
6372                                    public void performReceive(Intent intent, int resultCode,
6373                                            String data, Bundle extras, boolean ordered,
6374                                            boolean sticky, int sendingUser) {
6375                                        synchronized (ActivityManagerService.this) {
6376                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6377                                                    true, false);
6378                                        }
6379                                    }
6380                                },
6381                                0, null, null,
6382                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6383                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6384                                userId);
6385                    }
6386                }
6387                scheduleStartProfilesLocked();
6388            }
6389        }
6390    }
6391
6392    @Override
6393    public void bootAnimationComplete() {
6394        final boolean callFinishBooting;
6395        synchronized (this) {
6396            callFinishBooting = mCallFinishBooting;
6397            mBootAnimationComplete = true;
6398        }
6399        if (callFinishBooting) {
6400            finishBooting();
6401        }
6402    }
6403
6404    final void ensureBootCompleted() {
6405        boolean booting;
6406        boolean enableScreen;
6407        synchronized (this) {
6408            booting = mBooting;
6409            mBooting = false;
6410            enableScreen = !mBooted;
6411            mBooted = true;
6412        }
6413
6414        if (booting) {
6415            finishBooting();
6416        }
6417
6418        if (enableScreen) {
6419            enableScreenAfterBoot();
6420        }
6421    }
6422
6423    @Override
6424    public final void activityResumed(IBinder token) {
6425        final long origId = Binder.clearCallingIdentity();
6426        synchronized(this) {
6427            ActivityStack stack = ActivityRecord.getStackLocked(token);
6428            if (stack != null) {
6429                ActivityRecord.activityResumedLocked(token);
6430            }
6431        }
6432        Binder.restoreCallingIdentity(origId);
6433    }
6434
6435    @Override
6436    public final void activityPaused(IBinder token) {
6437        final long origId = Binder.clearCallingIdentity();
6438        synchronized(this) {
6439            ActivityStack stack = ActivityRecord.getStackLocked(token);
6440            if (stack != null) {
6441                stack.activityPausedLocked(token, false);
6442            }
6443        }
6444        Binder.restoreCallingIdentity(origId);
6445    }
6446
6447    @Override
6448    public final void activityStopped(IBinder token, Bundle icicle,
6449            PersistableBundle persistentState, CharSequence description) {
6450        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6451
6452        // Refuse possible leaked file descriptors
6453        if (icicle != null && icicle.hasFileDescriptors()) {
6454            throw new IllegalArgumentException("File descriptors passed in Bundle");
6455        }
6456
6457        final long origId = Binder.clearCallingIdentity();
6458
6459        synchronized (this) {
6460            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6461            if (r != null) {
6462                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6463            }
6464        }
6465
6466        trimApplications();
6467
6468        Binder.restoreCallingIdentity(origId);
6469    }
6470
6471    @Override
6472    public final void activityDestroyed(IBinder token) {
6473        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6474        synchronized (this) {
6475            ActivityStack stack = ActivityRecord.getStackLocked(token);
6476            if (stack != null) {
6477                stack.activityDestroyedLocked(token);
6478            }
6479        }
6480    }
6481
6482    @Override
6483    public final void backgroundResourcesReleased(IBinder token) {
6484        final long origId = Binder.clearCallingIdentity();
6485        try {
6486            synchronized (this) {
6487                ActivityStack stack = ActivityRecord.getStackLocked(token);
6488                if (stack != null) {
6489                    stack.backgroundResourcesReleased(token);
6490                }
6491            }
6492        } finally {
6493            Binder.restoreCallingIdentity(origId);
6494        }
6495    }
6496
6497    @Override
6498    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6499        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6500    }
6501
6502    @Override
6503    public final void notifyEnterAnimationComplete(IBinder token) {
6504        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6505    }
6506
6507    @Override
6508    public String getCallingPackage(IBinder token) {
6509        synchronized (this) {
6510            ActivityRecord r = getCallingRecordLocked(token);
6511            return r != null ? r.info.packageName : null;
6512        }
6513    }
6514
6515    @Override
6516    public ComponentName getCallingActivity(IBinder token) {
6517        synchronized (this) {
6518            ActivityRecord r = getCallingRecordLocked(token);
6519            return r != null ? r.intent.getComponent() : null;
6520        }
6521    }
6522
6523    private ActivityRecord getCallingRecordLocked(IBinder token) {
6524        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6525        if (r == null) {
6526            return null;
6527        }
6528        return r.resultTo;
6529    }
6530
6531    @Override
6532    public ComponentName getActivityClassForToken(IBinder token) {
6533        synchronized(this) {
6534            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6535            if (r == null) {
6536                return null;
6537            }
6538            return r.intent.getComponent();
6539        }
6540    }
6541
6542    @Override
6543    public String getPackageForToken(IBinder token) {
6544        synchronized(this) {
6545            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6546            if (r == null) {
6547                return null;
6548            }
6549            return r.packageName;
6550        }
6551    }
6552
6553    @Override
6554    public IIntentSender getIntentSender(int type,
6555            String packageName, IBinder token, String resultWho,
6556            int requestCode, Intent[] intents, String[] resolvedTypes,
6557            int flags, Bundle options, int userId) {
6558        enforceNotIsolatedCaller("getIntentSender");
6559        // Refuse possible leaked file descriptors
6560        if (intents != null) {
6561            if (intents.length < 1) {
6562                throw new IllegalArgumentException("Intents array length must be >= 1");
6563            }
6564            for (int i=0; i<intents.length; i++) {
6565                Intent intent = intents[i];
6566                if (intent != null) {
6567                    if (intent.hasFileDescriptors()) {
6568                        throw new IllegalArgumentException("File descriptors passed in Intent");
6569                    }
6570                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6571                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6572                        throw new IllegalArgumentException(
6573                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6574                    }
6575                    intents[i] = new Intent(intent);
6576                }
6577            }
6578            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6579                throw new IllegalArgumentException(
6580                        "Intent array length does not match resolvedTypes length");
6581            }
6582        }
6583        if (options != null) {
6584            if (options.hasFileDescriptors()) {
6585                throw new IllegalArgumentException("File descriptors passed in options");
6586            }
6587        }
6588
6589        synchronized(this) {
6590            int callingUid = Binder.getCallingUid();
6591            int origUserId = userId;
6592            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6593                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6594                    ALLOW_NON_FULL, "getIntentSender", null);
6595            if (origUserId == UserHandle.USER_CURRENT) {
6596                // We don't want to evaluate this until the pending intent is
6597                // actually executed.  However, we do want to always do the
6598                // security checking for it above.
6599                userId = UserHandle.USER_CURRENT;
6600            }
6601            try {
6602                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6603                    int uid = AppGlobals.getPackageManager()
6604                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6605                    if (!UserHandle.isSameApp(callingUid, uid)) {
6606                        String msg = "Permission Denial: getIntentSender() from pid="
6607                            + Binder.getCallingPid()
6608                            + ", uid=" + Binder.getCallingUid()
6609                            + ", (need uid=" + uid + ")"
6610                            + " is not allowed to send as package " + packageName;
6611                        Slog.w(TAG, msg);
6612                        throw new SecurityException(msg);
6613                    }
6614                }
6615
6616                return getIntentSenderLocked(type, packageName, callingUid, userId,
6617                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6618
6619            } catch (RemoteException e) {
6620                throw new SecurityException(e);
6621            }
6622        }
6623    }
6624
6625    IIntentSender getIntentSenderLocked(int type, String packageName,
6626            int callingUid, int userId, IBinder token, String resultWho,
6627            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6628            Bundle options) {
6629        if (DEBUG_MU)
6630            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6631        ActivityRecord activity = null;
6632        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6633            activity = ActivityRecord.isInStackLocked(token);
6634            if (activity == null) {
6635                return null;
6636            }
6637            if (activity.finishing) {
6638                return null;
6639            }
6640        }
6641
6642        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6643        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6644        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6645        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6646                |PendingIntent.FLAG_UPDATE_CURRENT);
6647
6648        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6649                type, packageName, activity, resultWho,
6650                requestCode, intents, resolvedTypes, flags, options, userId);
6651        WeakReference<PendingIntentRecord> ref;
6652        ref = mIntentSenderRecords.get(key);
6653        PendingIntentRecord rec = ref != null ? ref.get() : null;
6654        if (rec != null) {
6655            if (!cancelCurrent) {
6656                if (updateCurrent) {
6657                    if (rec.key.requestIntent != null) {
6658                        rec.key.requestIntent.replaceExtras(intents != null ?
6659                                intents[intents.length - 1] : null);
6660                    }
6661                    if (intents != null) {
6662                        intents[intents.length-1] = rec.key.requestIntent;
6663                        rec.key.allIntents = intents;
6664                        rec.key.allResolvedTypes = resolvedTypes;
6665                    } else {
6666                        rec.key.allIntents = null;
6667                        rec.key.allResolvedTypes = null;
6668                    }
6669                }
6670                return rec;
6671            }
6672            rec.canceled = true;
6673            mIntentSenderRecords.remove(key);
6674        }
6675        if (noCreate) {
6676            return rec;
6677        }
6678        rec = new PendingIntentRecord(this, key, callingUid);
6679        mIntentSenderRecords.put(key, rec.ref);
6680        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6681            if (activity.pendingResults == null) {
6682                activity.pendingResults
6683                        = new HashSet<WeakReference<PendingIntentRecord>>();
6684            }
6685            activity.pendingResults.add(rec.ref);
6686        }
6687        return rec;
6688    }
6689
6690    @Override
6691    public void cancelIntentSender(IIntentSender sender) {
6692        if (!(sender instanceof PendingIntentRecord)) {
6693            return;
6694        }
6695        synchronized(this) {
6696            PendingIntentRecord rec = (PendingIntentRecord)sender;
6697            try {
6698                int uid = AppGlobals.getPackageManager()
6699                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6700                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6701                    String msg = "Permission Denial: cancelIntentSender() from pid="
6702                        + Binder.getCallingPid()
6703                        + ", uid=" + Binder.getCallingUid()
6704                        + " is not allowed to cancel packges "
6705                        + rec.key.packageName;
6706                    Slog.w(TAG, msg);
6707                    throw new SecurityException(msg);
6708                }
6709            } catch (RemoteException e) {
6710                throw new SecurityException(e);
6711            }
6712            cancelIntentSenderLocked(rec, true);
6713        }
6714    }
6715
6716    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6717        rec.canceled = true;
6718        mIntentSenderRecords.remove(rec.key);
6719        if (cleanActivity && rec.key.activity != null) {
6720            rec.key.activity.pendingResults.remove(rec.ref);
6721        }
6722    }
6723
6724    @Override
6725    public String getPackageForIntentSender(IIntentSender pendingResult) {
6726        if (!(pendingResult instanceof PendingIntentRecord)) {
6727            return null;
6728        }
6729        try {
6730            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6731            return res.key.packageName;
6732        } catch (ClassCastException e) {
6733        }
6734        return null;
6735    }
6736
6737    @Override
6738    public int getUidForIntentSender(IIntentSender sender) {
6739        if (sender instanceof PendingIntentRecord) {
6740            try {
6741                PendingIntentRecord res = (PendingIntentRecord)sender;
6742                return res.uid;
6743            } catch (ClassCastException e) {
6744            }
6745        }
6746        return -1;
6747    }
6748
6749    @Override
6750    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6751        if (!(pendingResult instanceof PendingIntentRecord)) {
6752            return false;
6753        }
6754        try {
6755            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6756            if (res.key.allIntents == null) {
6757                return false;
6758            }
6759            for (int i=0; i<res.key.allIntents.length; i++) {
6760                Intent intent = res.key.allIntents[i];
6761                if (intent.getPackage() != null && intent.getComponent() != null) {
6762                    return false;
6763                }
6764            }
6765            return true;
6766        } catch (ClassCastException e) {
6767        }
6768        return false;
6769    }
6770
6771    @Override
6772    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6773        if (!(pendingResult instanceof PendingIntentRecord)) {
6774            return false;
6775        }
6776        try {
6777            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6778            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6779                return true;
6780            }
6781            return false;
6782        } catch (ClassCastException e) {
6783        }
6784        return false;
6785    }
6786
6787    @Override
6788    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6789        if (!(pendingResult instanceof PendingIntentRecord)) {
6790            return null;
6791        }
6792        try {
6793            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6794            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6795        } catch (ClassCastException e) {
6796        }
6797        return null;
6798    }
6799
6800    @Override
6801    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6802        if (!(pendingResult instanceof PendingIntentRecord)) {
6803            return null;
6804        }
6805        try {
6806            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6807            Intent intent = res.key.requestIntent;
6808            if (intent != null) {
6809                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6810                        || res.lastTagPrefix.equals(prefix))) {
6811                    return res.lastTag;
6812                }
6813                res.lastTagPrefix = prefix;
6814                StringBuilder sb = new StringBuilder(128);
6815                if (prefix != null) {
6816                    sb.append(prefix);
6817                }
6818                if (intent.getAction() != null) {
6819                    sb.append(intent.getAction());
6820                } else if (intent.getComponent() != null) {
6821                    intent.getComponent().appendShortString(sb);
6822                } else {
6823                    sb.append("?");
6824                }
6825                return res.lastTag = sb.toString();
6826            }
6827        } catch (ClassCastException e) {
6828        }
6829        return null;
6830    }
6831
6832    @Override
6833    public void setProcessLimit(int max) {
6834        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6835                "setProcessLimit()");
6836        synchronized (this) {
6837            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6838            mProcessLimitOverride = max;
6839        }
6840        trimApplications();
6841    }
6842
6843    @Override
6844    public int getProcessLimit() {
6845        synchronized (this) {
6846            return mProcessLimitOverride;
6847        }
6848    }
6849
6850    void foregroundTokenDied(ForegroundToken token) {
6851        synchronized (ActivityManagerService.this) {
6852            synchronized (mPidsSelfLocked) {
6853                ForegroundToken cur
6854                    = mForegroundProcesses.get(token.pid);
6855                if (cur != token) {
6856                    return;
6857                }
6858                mForegroundProcesses.remove(token.pid);
6859                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6860                if (pr == null) {
6861                    return;
6862                }
6863                pr.forcingToForeground = null;
6864                updateProcessForegroundLocked(pr, false, false);
6865            }
6866            updateOomAdjLocked();
6867        }
6868    }
6869
6870    @Override
6871    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6872        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6873                "setProcessForeground()");
6874        synchronized(this) {
6875            boolean changed = false;
6876
6877            synchronized (mPidsSelfLocked) {
6878                ProcessRecord pr = mPidsSelfLocked.get(pid);
6879                if (pr == null && isForeground) {
6880                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6881                    return;
6882                }
6883                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6884                if (oldToken != null) {
6885                    oldToken.token.unlinkToDeath(oldToken, 0);
6886                    mForegroundProcesses.remove(pid);
6887                    if (pr != null) {
6888                        pr.forcingToForeground = null;
6889                    }
6890                    changed = true;
6891                }
6892                if (isForeground && token != null) {
6893                    ForegroundToken newToken = new ForegroundToken() {
6894                        @Override
6895                        public void binderDied() {
6896                            foregroundTokenDied(this);
6897                        }
6898                    };
6899                    newToken.pid = pid;
6900                    newToken.token = token;
6901                    try {
6902                        token.linkToDeath(newToken, 0);
6903                        mForegroundProcesses.put(pid, newToken);
6904                        pr.forcingToForeground = token;
6905                        changed = true;
6906                    } catch (RemoteException e) {
6907                        // If the process died while doing this, we will later
6908                        // do the cleanup with the process death link.
6909                    }
6910                }
6911            }
6912
6913            if (changed) {
6914                updateOomAdjLocked();
6915            }
6916        }
6917    }
6918
6919    // =========================================================
6920    // PERMISSIONS
6921    // =========================================================
6922
6923    static class PermissionController extends IPermissionController.Stub {
6924        ActivityManagerService mActivityManagerService;
6925        PermissionController(ActivityManagerService activityManagerService) {
6926            mActivityManagerService = activityManagerService;
6927        }
6928
6929        @Override
6930        public boolean checkPermission(String permission, int pid, int uid) {
6931            return mActivityManagerService.checkPermission(permission, pid,
6932                    uid) == PackageManager.PERMISSION_GRANTED;
6933        }
6934    }
6935
6936    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6937        @Override
6938        public int checkComponentPermission(String permission, int pid, int uid,
6939                int owningUid, boolean exported) {
6940            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6941                    owningUid, exported);
6942        }
6943
6944        @Override
6945        public Object getAMSLock() {
6946            return ActivityManagerService.this;
6947        }
6948    }
6949
6950    /**
6951     * This can be called with or without the global lock held.
6952     */
6953    int checkComponentPermission(String permission, int pid, int uid,
6954            int owningUid, boolean exported) {
6955        // We might be performing an operation on behalf of an indirect binder
6956        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6957        // client identity accordingly before proceeding.
6958        Identity tlsIdentity = sCallerIdentity.get();
6959        if (tlsIdentity != null) {
6960            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6961                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6962            uid = tlsIdentity.uid;
6963            pid = tlsIdentity.pid;
6964        }
6965
6966        if (pid == MY_PID) {
6967            return PackageManager.PERMISSION_GRANTED;
6968        }
6969
6970        return ActivityManager.checkComponentPermission(permission, uid,
6971                owningUid, exported);
6972    }
6973
6974    /**
6975     * As the only public entry point for permissions checking, this method
6976     * can enforce the semantic that requesting a check on a null global
6977     * permission is automatically denied.  (Internally a null permission
6978     * string is used when calling {@link #checkComponentPermission} in cases
6979     * when only uid-based security is needed.)
6980     *
6981     * This can be called with or without the global lock held.
6982     */
6983    @Override
6984    public int checkPermission(String permission, int pid, int uid) {
6985        if (permission == null) {
6986            return PackageManager.PERMISSION_DENIED;
6987        }
6988        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6989    }
6990
6991    /**
6992     * Binder IPC calls go through the public entry point.
6993     * This can be called with or without the global lock held.
6994     */
6995    int checkCallingPermission(String permission) {
6996        return checkPermission(permission,
6997                Binder.getCallingPid(),
6998                UserHandle.getAppId(Binder.getCallingUid()));
6999    }
7000
7001    /**
7002     * This can be called with or without the global lock held.
7003     */
7004    void enforceCallingPermission(String permission, String func) {
7005        if (checkCallingPermission(permission)
7006                == PackageManager.PERMISSION_GRANTED) {
7007            return;
7008        }
7009
7010        String msg = "Permission Denial: " + func + " from pid="
7011                + Binder.getCallingPid()
7012                + ", uid=" + Binder.getCallingUid()
7013                + " requires " + permission;
7014        Slog.w(TAG, msg);
7015        throw new SecurityException(msg);
7016    }
7017
7018    /**
7019     * Determine if UID is holding permissions required to access {@link Uri} in
7020     * the given {@link ProviderInfo}. Final permission checking is always done
7021     * in {@link ContentProvider}.
7022     */
7023    private final boolean checkHoldingPermissionsLocked(
7024            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7025        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7026                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7027        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7028            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7029                    != PERMISSION_GRANTED) {
7030                return false;
7031            }
7032        }
7033        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7034    }
7035
7036    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7037            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7038        if (pi.applicationInfo.uid == uid) {
7039            return true;
7040        } else if (!pi.exported) {
7041            return false;
7042        }
7043
7044        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7045        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7046        try {
7047            // check if target holds top-level <provider> permissions
7048            if (!readMet && pi.readPermission != null && considerUidPermissions
7049                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7050                readMet = true;
7051            }
7052            if (!writeMet && pi.writePermission != null && considerUidPermissions
7053                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7054                writeMet = true;
7055            }
7056
7057            // track if unprotected read/write is allowed; any denied
7058            // <path-permission> below removes this ability
7059            boolean allowDefaultRead = pi.readPermission == null;
7060            boolean allowDefaultWrite = pi.writePermission == null;
7061
7062            // check if target holds any <path-permission> that match uri
7063            final PathPermission[] pps = pi.pathPermissions;
7064            if (pps != null) {
7065                final String path = grantUri.uri.getPath();
7066                int i = pps.length;
7067                while (i > 0 && (!readMet || !writeMet)) {
7068                    i--;
7069                    PathPermission pp = pps[i];
7070                    if (pp.match(path)) {
7071                        if (!readMet) {
7072                            final String pprperm = pp.getReadPermission();
7073                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7074                                    + pprperm + " for " + pp.getPath()
7075                                    + ": match=" + pp.match(path)
7076                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7077                            if (pprperm != null) {
7078                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7079                                        == PERMISSION_GRANTED) {
7080                                    readMet = true;
7081                                } else {
7082                                    allowDefaultRead = false;
7083                                }
7084                            }
7085                        }
7086                        if (!writeMet) {
7087                            final String ppwperm = pp.getWritePermission();
7088                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7089                                    + ppwperm + " for " + pp.getPath()
7090                                    + ": match=" + pp.match(path)
7091                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7092                            if (ppwperm != null) {
7093                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7094                                        == PERMISSION_GRANTED) {
7095                                    writeMet = true;
7096                                } else {
7097                                    allowDefaultWrite = false;
7098                                }
7099                            }
7100                        }
7101                    }
7102                }
7103            }
7104
7105            // grant unprotected <provider> read/write, if not blocked by
7106            // <path-permission> above
7107            if (allowDefaultRead) readMet = true;
7108            if (allowDefaultWrite) writeMet = true;
7109
7110        } catch (RemoteException e) {
7111            return false;
7112        }
7113
7114        return readMet && writeMet;
7115    }
7116
7117    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7118        ProviderInfo pi = null;
7119        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7120        if (cpr != null) {
7121            pi = cpr.info;
7122        } else {
7123            try {
7124                pi = AppGlobals.getPackageManager().resolveContentProvider(
7125                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7126            } catch (RemoteException ex) {
7127            }
7128        }
7129        return pi;
7130    }
7131
7132    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7133        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7134        if (targetUris != null) {
7135            return targetUris.get(grantUri);
7136        }
7137        return null;
7138    }
7139
7140    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7141            String targetPkg, int targetUid, GrantUri grantUri) {
7142        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7143        if (targetUris == null) {
7144            targetUris = Maps.newArrayMap();
7145            mGrantedUriPermissions.put(targetUid, targetUris);
7146        }
7147
7148        UriPermission perm = targetUris.get(grantUri);
7149        if (perm == null) {
7150            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7151            targetUris.put(grantUri, perm);
7152        }
7153
7154        return perm;
7155    }
7156
7157    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7158            final int modeFlags) {
7159        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7160        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7161                : UriPermission.STRENGTH_OWNED;
7162
7163        // Root gets to do everything.
7164        if (uid == 0) {
7165            return true;
7166        }
7167
7168        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7169        if (perms == null) return false;
7170
7171        // First look for exact match
7172        final UriPermission exactPerm = perms.get(grantUri);
7173        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7174            return true;
7175        }
7176
7177        // No exact match, look for prefixes
7178        final int N = perms.size();
7179        for (int i = 0; i < N; i++) {
7180            final UriPermission perm = perms.valueAt(i);
7181            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7182                    && perm.getStrength(modeFlags) >= minStrength) {
7183                return true;
7184            }
7185        }
7186
7187        return false;
7188    }
7189
7190    /**
7191     * @param uri This uri must NOT contain an embedded userId.
7192     * @param userId The userId in which the uri is to be resolved.
7193     */
7194    @Override
7195    public int checkUriPermission(Uri uri, int pid, int uid,
7196            final int modeFlags, int userId) {
7197        enforceNotIsolatedCaller("checkUriPermission");
7198
7199        // Another redirected-binder-call permissions check as in
7200        // {@link checkComponentPermission}.
7201        Identity tlsIdentity = sCallerIdentity.get();
7202        if (tlsIdentity != null) {
7203            uid = tlsIdentity.uid;
7204            pid = tlsIdentity.pid;
7205        }
7206
7207        // Our own process gets to do everything.
7208        if (pid == MY_PID) {
7209            return PackageManager.PERMISSION_GRANTED;
7210        }
7211        synchronized (this) {
7212            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7213                    ? PackageManager.PERMISSION_GRANTED
7214                    : PackageManager.PERMISSION_DENIED;
7215        }
7216    }
7217
7218    /**
7219     * Check if the targetPkg can be granted permission to access uri by
7220     * the callingUid using the given modeFlags.  Throws a security exception
7221     * if callingUid is not allowed to do this.  Returns the uid of the target
7222     * if the URI permission grant should be performed; returns -1 if it is not
7223     * needed (for example targetPkg already has permission to access the URI).
7224     * If you already know the uid of the target, you can supply it in
7225     * lastTargetUid else set that to -1.
7226     */
7227    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7228            final int modeFlags, int lastTargetUid) {
7229        if (!Intent.isAccessUriMode(modeFlags)) {
7230            return -1;
7231        }
7232
7233        if (targetPkg != null) {
7234            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7235                    "Checking grant " + targetPkg + " permission to " + grantUri);
7236        }
7237
7238        final IPackageManager pm = AppGlobals.getPackageManager();
7239
7240        // If this is not a content: uri, we can't do anything with it.
7241        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7242            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7243                    "Can't grant URI permission for non-content URI: " + grantUri);
7244            return -1;
7245        }
7246
7247        final String authority = grantUri.uri.getAuthority();
7248        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7249        if (pi == null) {
7250            Slog.w(TAG, "No content provider found for permission check: " +
7251                    grantUri.uri.toSafeString());
7252            return -1;
7253        }
7254
7255        int targetUid = lastTargetUid;
7256        if (targetUid < 0 && targetPkg != null) {
7257            try {
7258                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7259                if (targetUid < 0) {
7260                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7261                            "Can't grant URI permission no uid for: " + targetPkg);
7262                    return -1;
7263                }
7264            } catch (RemoteException ex) {
7265                return -1;
7266            }
7267        }
7268
7269        if (targetUid >= 0) {
7270            // First...  does the target actually need this permission?
7271            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7272                // No need to grant the target this permission.
7273                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7274                        "Target " + targetPkg + " already has full permission to " + grantUri);
7275                return -1;
7276            }
7277        } else {
7278            // First...  there is no target package, so can anyone access it?
7279            boolean allowed = pi.exported;
7280            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7281                if (pi.readPermission != null) {
7282                    allowed = false;
7283                }
7284            }
7285            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7286                if (pi.writePermission != null) {
7287                    allowed = false;
7288                }
7289            }
7290            if (allowed) {
7291                return -1;
7292            }
7293        }
7294
7295        /* There is a special cross user grant if:
7296         * - The target is on another user.
7297         * - Apps on the current user can access the uri without any uid permissions.
7298         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7299         * grant uri permissions.
7300         */
7301        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7302                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7303                modeFlags, false /*without considering the uid permissions*/);
7304
7305        // Second...  is the provider allowing granting of URI permissions?
7306        if (!specialCrossUserGrant) {
7307            if (!pi.grantUriPermissions) {
7308                throw new SecurityException("Provider " + pi.packageName
7309                        + "/" + pi.name
7310                        + " does not allow granting of Uri permissions (uri "
7311                        + grantUri + ")");
7312            }
7313            if (pi.uriPermissionPatterns != null) {
7314                final int N = pi.uriPermissionPatterns.length;
7315                boolean allowed = false;
7316                for (int i=0; i<N; i++) {
7317                    if (pi.uriPermissionPatterns[i] != null
7318                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7319                        allowed = true;
7320                        break;
7321                    }
7322                }
7323                if (!allowed) {
7324                    throw new SecurityException("Provider " + pi.packageName
7325                            + "/" + pi.name
7326                            + " does not allow granting of permission to path of Uri "
7327                            + grantUri);
7328                }
7329            }
7330        }
7331
7332        // Third...  does the caller itself have permission to access
7333        // this uri?
7334        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7335            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7336                // Require they hold a strong enough Uri permission
7337                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7338                    throw new SecurityException("Uid " + callingUid
7339                            + " does not have permission to uri " + grantUri);
7340                }
7341            }
7342        }
7343        return targetUid;
7344    }
7345
7346    /**
7347     * @param uri This uri must NOT contain an embedded userId.
7348     * @param userId The userId in which the uri is to be resolved.
7349     */
7350    @Override
7351    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7352            final int modeFlags, int userId) {
7353        enforceNotIsolatedCaller("checkGrantUriPermission");
7354        synchronized(this) {
7355            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7356                    new GrantUri(userId, uri, false), modeFlags, -1);
7357        }
7358    }
7359
7360    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7361            final int modeFlags, UriPermissionOwner owner) {
7362        if (!Intent.isAccessUriMode(modeFlags)) {
7363            return;
7364        }
7365
7366        // So here we are: the caller has the assumed permission
7367        // to the uri, and the target doesn't.  Let's now give this to
7368        // the target.
7369
7370        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7371                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7372
7373        final String authority = grantUri.uri.getAuthority();
7374        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7375        if (pi == null) {
7376            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7377            return;
7378        }
7379
7380        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7381            grantUri.prefix = true;
7382        }
7383        final UriPermission perm = findOrCreateUriPermissionLocked(
7384                pi.packageName, targetPkg, targetUid, grantUri);
7385        perm.grantModes(modeFlags, owner);
7386    }
7387
7388    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7389            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7390        if (targetPkg == null) {
7391            throw new NullPointerException("targetPkg");
7392        }
7393        int targetUid;
7394        final IPackageManager pm = AppGlobals.getPackageManager();
7395        try {
7396            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7397        } catch (RemoteException ex) {
7398            return;
7399        }
7400
7401        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7402                targetUid);
7403        if (targetUid < 0) {
7404            return;
7405        }
7406
7407        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7408                owner);
7409    }
7410
7411    static class NeededUriGrants extends ArrayList<GrantUri> {
7412        final String targetPkg;
7413        final int targetUid;
7414        final int flags;
7415
7416        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7417            this.targetPkg = targetPkg;
7418            this.targetUid = targetUid;
7419            this.flags = flags;
7420        }
7421    }
7422
7423    /**
7424     * Like checkGrantUriPermissionLocked, but takes an Intent.
7425     */
7426    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7427            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7428        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7429                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7430                + " clip=" + (intent != null ? intent.getClipData() : null)
7431                + " from " + intent + "; flags=0x"
7432                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7433
7434        if (targetPkg == null) {
7435            throw new NullPointerException("targetPkg");
7436        }
7437
7438        if (intent == null) {
7439            return null;
7440        }
7441        Uri data = intent.getData();
7442        ClipData clip = intent.getClipData();
7443        if (data == null && clip == null) {
7444            return null;
7445        }
7446        // Default userId for uris in the intent (if they don't specify it themselves)
7447        int contentUserHint = intent.getContentUserHint();
7448        if (contentUserHint == UserHandle.USER_CURRENT) {
7449            contentUserHint = UserHandle.getUserId(callingUid);
7450        }
7451        final IPackageManager pm = AppGlobals.getPackageManager();
7452        int targetUid;
7453        if (needed != null) {
7454            targetUid = needed.targetUid;
7455        } else {
7456            try {
7457                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7458            } catch (RemoteException ex) {
7459                return null;
7460            }
7461            if (targetUid < 0) {
7462                if (DEBUG_URI_PERMISSION) {
7463                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7464                            + " on user " + targetUserId);
7465                }
7466                return null;
7467            }
7468        }
7469        if (data != null) {
7470            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7471            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7472                    targetUid);
7473            if (targetUid > 0) {
7474                if (needed == null) {
7475                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7476                }
7477                needed.add(grantUri);
7478            }
7479        }
7480        if (clip != null) {
7481            for (int i=0; i<clip.getItemCount(); i++) {
7482                Uri uri = clip.getItemAt(i).getUri();
7483                if (uri != null) {
7484                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7485                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7486                            targetUid);
7487                    if (targetUid > 0) {
7488                        if (needed == null) {
7489                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7490                        }
7491                        needed.add(grantUri);
7492                    }
7493                } else {
7494                    Intent clipIntent = clip.getItemAt(i).getIntent();
7495                    if (clipIntent != null) {
7496                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7497                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7498                        if (newNeeded != null) {
7499                            needed = newNeeded;
7500                        }
7501                    }
7502                }
7503            }
7504        }
7505
7506        return needed;
7507    }
7508
7509    /**
7510     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7511     */
7512    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7513            UriPermissionOwner owner) {
7514        if (needed != null) {
7515            for (int i=0; i<needed.size(); i++) {
7516                GrantUri grantUri = needed.get(i);
7517                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7518                        grantUri, needed.flags, owner);
7519            }
7520        }
7521    }
7522
7523    void grantUriPermissionFromIntentLocked(int callingUid,
7524            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7525        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7526                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7527        if (needed == null) {
7528            return;
7529        }
7530
7531        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7532    }
7533
7534    /**
7535     * @param uri This uri must NOT contain an embedded userId.
7536     * @param userId The userId in which the uri is to be resolved.
7537     */
7538    @Override
7539    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7540            final int modeFlags, int userId) {
7541        enforceNotIsolatedCaller("grantUriPermission");
7542        GrantUri grantUri = new GrantUri(userId, uri, false);
7543        synchronized(this) {
7544            final ProcessRecord r = getRecordForAppLocked(caller);
7545            if (r == null) {
7546                throw new SecurityException("Unable to find app for caller "
7547                        + caller
7548                        + " when granting permission to uri " + grantUri);
7549            }
7550            if (targetPkg == null) {
7551                throw new IllegalArgumentException("null target");
7552            }
7553            if (grantUri == null) {
7554                throw new IllegalArgumentException("null uri");
7555            }
7556
7557            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7558                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7559                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7560                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7561
7562            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7563                    UserHandle.getUserId(r.uid));
7564        }
7565    }
7566
7567    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7568        if (perm.modeFlags == 0) {
7569            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7570                    perm.targetUid);
7571            if (perms != null) {
7572                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7573                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7574
7575                perms.remove(perm.uri);
7576                if (perms.isEmpty()) {
7577                    mGrantedUriPermissions.remove(perm.targetUid);
7578                }
7579            }
7580        }
7581    }
7582
7583    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7584        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7585
7586        final IPackageManager pm = AppGlobals.getPackageManager();
7587        final String authority = grantUri.uri.getAuthority();
7588        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7589        if (pi == null) {
7590            Slog.w(TAG, "No content provider found for permission revoke: "
7591                    + grantUri.toSafeString());
7592            return;
7593        }
7594
7595        // Does the caller have this permission on the URI?
7596        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7597            // If they don't have direct access to the URI, then revoke any
7598            // ownerless URI permissions that have been granted to them.
7599            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7600            if (perms != null) {
7601                boolean persistChanged = false;
7602                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7603                    final UriPermission perm = it.next();
7604                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7605                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7606                        if (DEBUG_URI_PERMISSION)
7607                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7608                                    " permission to " + perm.uri);
7609                        persistChanged |= perm.revokeModes(
7610                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7611                        if (perm.modeFlags == 0) {
7612                            it.remove();
7613                        }
7614                    }
7615                }
7616                if (perms.isEmpty()) {
7617                    mGrantedUriPermissions.remove(callingUid);
7618                }
7619                if (persistChanged) {
7620                    schedulePersistUriGrants();
7621                }
7622            }
7623            return;
7624        }
7625
7626        boolean persistChanged = false;
7627
7628        // Go through all of the permissions and remove any that match.
7629        int N = mGrantedUriPermissions.size();
7630        for (int i = 0; i < N; i++) {
7631            final int targetUid = mGrantedUriPermissions.keyAt(i);
7632            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7633
7634            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7635                final UriPermission perm = it.next();
7636                if (perm.uri.sourceUserId == grantUri.sourceUserId
7637                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7638                    if (DEBUG_URI_PERMISSION)
7639                        Slog.v(TAG,
7640                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7641                    persistChanged |= perm.revokeModes(
7642                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7643                    if (perm.modeFlags == 0) {
7644                        it.remove();
7645                    }
7646                }
7647            }
7648
7649            if (perms.isEmpty()) {
7650                mGrantedUriPermissions.remove(targetUid);
7651                N--;
7652                i--;
7653            }
7654        }
7655
7656        if (persistChanged) {
7657            schedulePersistUriGrants();
7658        }
7659    }
7660
7661    /**
7662     * @param uri This uri must NOT contain an embedded userId.
7663     * @param userId The userId in which the uri is to be resolved.
7664     */
7665    @Override
7666    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7667            int userId) {
7668        enforceNotIsolatedCaller("revokeUriPermission");
7669        synchronized(this) {
7670            final ProcessRecord r = getRecordForAppLocked(caller);
7671            if (r == null) {
7672                throw new SecurityException("Unable to find app for caller "
7673                        + caller
7674                        + " when revoking permission to uri " + uri);
7675            }
7676            if (uri == null) {
7677                Slog.w(TAG, "revokeUriPermission: null uri");
7678                return;
7679            }
7680
7681            if (!Intent.isAccessUriMode(modeFlags)) {
7682                return;
7683            }
7684
7685            final IPackageManager pm = AppGlobals.getPackageManager();
7686            final String authority = uri.getAuthority();
7687            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7688            if (pi == null) {
7689                Slog.w(TAG, "No content provider found for permission revoke: "
7690                        + uri.toSafeString());
7691                return;
7692            }
7693
7694            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7695        }
7696    }
7697
7698    /**
7699     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7700     * given package.
7701     *
7702     * @param packageName Package name to match, or {@code null} to apply to all
7703     *            packages.
7704     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7705     *            to all users.
7706     * @param persistable If persistable grants should be removed.
7707     */
7708    private void removeUriPermissionsForPackageLocked(
7709            String packageName, int userHandle, boolean persistable) {
7710        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7711            throw new IllegalArgumentException("Must narrow by either package or user");
7712        }
7713
7714        boolean persistChanged = false;
7715
7716        int N = mGrantedUriPermissions.size();
7717        for (int i = 0; i < N; i++) {
7718            final int targetUid = mGrantedUriPermissions.keyAt(i);
7719            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7720
7721            // Only inspect grants matching user
7722            if (userHandle == UserHandle.USER_ALL
7723                    || userHandle == UserHandle.getUserId(targetUid)) {
7724                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7725                    final UriPermission perm = it.next();
7726
7727                    // Only inspect grants matching package
7728                    if (packageName == null || perm.sourcePkg.equals(packageName)
7729                            || perm.targetPkg.equals(packageName)) {
7730                        persistChanged |= perm.revokeModes(persistable
7731                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7732
7733                        // Only remove when no modes remain; any persisted grants
7734                        // will keep this alive.
7735                        if (perm.modeFlags == 0) {
7736                            it.remove();
7737                        }
7738                    }
7739                }
7740
7741                if (perms.isEmpty()) {
7742                    mGrantedUriPermissions.remove(targetUid);
7743                    N--;
7744                    i--;
7745                }
7746            }
7747        }
7748
7749        if (persistChanged) {
7750            schedulePersistUriGrants();
7751        }
7752    }
7753
7754    @Override
7755    public IBinder newUriPermissionOwner(String name) {
7756        enforceNotIsolatedCaller("newUriPermissionOwner");
7757        synchronized(this) {
7758            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7759            return owner.getExternalTokenLocked();
7760        }
7761    }
7762
7763    /**
7764     * @param uri This uri must NOT contain an embedded userId.
7765     * @param sourceUserId The userId in which the uri is to be resolved.
7766     * @param targetUserId The userId of the app that receives the grant.
7767     */
7768    @Override
7769    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7770            final int modeFlags, int sourceUserId, int targetUserId) {
7771        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7772                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7773        synchronized(this) {
7774            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7775            if (owner == null) {
7776                throw new IllegalArgumentException("Unknown owner: " + token);
7777            }
7778            if (fromUid != Binder.getCallingUid()) {
7779                if (Binder.getCallingUid() != Process.myUid()) {
7780                    // Only system code can grant URI permissions on behalf
7781                    // of other users.
7782                    throw new SecurityException("nice try");
7783                }
7784            }
7785            if (targetPkg == null) {
7786                throw new IllegalArgumentException("null target");
7787            }
7788            if (uri == null) {
7789                throw new IllegalArgumentException("null uri");
7790            }
7791
7792            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7793                    modeFlags, owner, targetUserId);
7794        }
7795    }
7796
7797    /**
7798     * @param uri This uri must NOT contain an embedded userId.
7799     * @param userId The userId in which the uri is to be resolved.
7800     */
7801    @Override
7802    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7803        synchronized(this) {
7804            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7805            if (owner == null) {
7806                throw new IllegalArgumentException("Unknown owner: " + token);
7807            }
7808
7809            if (uri == null) {
7810                owner.removeUriPermissionsLocked(mode);
7811            } else {
7812                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7813            }
7814        }
7815    }
7816
7817    private void schedulePersistUriGrants() {
7818        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7819            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7820                    10 * DateUtils.SECOND_IN_MILLIS);
7821        }
7822    }
7823
7824    private void writeGrantedUriPermissions() {
7825        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7826
7827        // Snapshot permissions so we can persist without lock
7828        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7829        synchronized (this) {
7830            final int size = mGrantedUriPermissions.size();
7831            for (int i = 0; i < size; i++) {
7832                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7833                for (UriPermission perm : perms.values()) {
7834                    if (perm.persistedModeFlags != 0) {
7835                        persist.add(perm.snapshot());
7836                    }
7837                }
7838            }
7839        }
7840
7841        FileOutputStream fos = null;
7842        try {
7843            fos = mGrantFile.startWrite();
7844
7845            XmlSerializer out = new FastXmlSerializer();
7846            out.setOutput(fos, "utf-8");
7847            out.startDocument(null, true);
7848            out.startTag(null, TAG_URI_GRANTS);
7849            for (UriPermission.Snapshot perm : persist) {
7850                out.startTag(null, TAG_URI_GRANT);
7851                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7852                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7853                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7854                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7855                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7856                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7857                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7858                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7859                out.endTag(null, TAG_URI_GRANT);
7860            }
7861            out.endTag(null, TAG_URI_GRANTS);
7862            out.endDocument();
7863
7864            mGrantFile.finishWrite(fos);
7865        } catch (IOException e) {
7866            if (fos != null) {
7867                mGrantFile.failWrite(fos);
7868            }
7869        }
7870    }
7871
7872    private void readGrantedUriPermissionsLocked() {
7873        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7874
7875        final long now = System.currentTimeMillis();
7876
7877        FileInputStream fis = null;
7878        try {
7879            fis = mGrantFile.openRead();
7880            final XmlPullParser in = Xml.newPullParser();
7881            in.setInput(fis, null);
7882
7883            int type;
7884            while ((type = in.next()) != END_DOCUMENT) {
7885                final String tag = in.getName();
7886                if (type == START_TAG) {
7887                    if (TAG_URI_GRANT.equals(tag)) {
7888                        final int sourceUserId;
7889                        final int targetUserId;
7890                        final int userHandle = readIntAttribute(in,
7891                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7892                        if (userHandle != UserHandle.USER_NULL) {
7893                            // For backwards compatibility.
7894                            sourceUserId = userHandle;
7895                            targetUserId = userHandle;
7896                        } else {
7897                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7898                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7899                        }
7900                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7901                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7902                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7903                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7904                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7905                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7906
7907                        // Sanity check that provider still belongs to source package
7908                        final ProviderInfo pi = getProviderInfoLocked(
7909                                uri.getAuthority(), sourceUserId);
7910                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7911                            int targetUid = -1;
7912                            try {
7913                                targetUid = AppGlobals.getPackageManager()
7914                                        .getPackageUid(targetPkg, targetUserId);
7915                            } catch (RemoteException e) {
7916                            }
7917                            if (targetUid != -1) {
7918                                final UriPermission perm = findOrCreateUriPermissionLocked(
7919                                        sourcePkg, targetPkg, targetUid,
7920                                        new GrantUri(sourceUserId, uri, prefix));
7921                                perm.initPersistedModes(modeFlags, createdTime);
7922                            }
7923                        } else {
7924                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7925                                    + " but instead found " + pi);
7926                        }
7927                    }
7928                }
7929            }
7930        } catch (FileNotFoundException e) {
7931            // Missing grants is okay
7932        } catch (IOException e) {
7933            Slog.wtf(TAG, "Failed reading Uri grants", e);
7934        } catch (XmlPullParserException e) {
7935            Slog.wtf(TAG, "Failed reading Uri grants", e);
7936        } finally {
7937            IoUtils.closeQuietly(fis);
7938        }
7939    }
7940
7941    /**
7942     * @param uri This uri must NOT contain an embedded userId.
7943     * @param userId The userId in which the uri is to be resolved.
7944     */
7945    @Override
7946    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7947        enforceNotIsolatedCaller("takePersistableUriPermission");
7948
7949        Preconditions.checkFlagsArgument(modeFlags,
7950                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7951
7952        synchronized (this) {
7953            final int callingUid = Binder.getCallingUid();
7954            boolean persistChanged = false;
7955            GrantUri grantUri = new GrantUri(userId, uri, false);
7956
7957            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7958                    new GrantUri(userId, uri, false));
7959            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7960                    new GrantUri(userId, uri, true));
7961
7962            final boolean exactValid = (exactPerm != null)
7963                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7964            final boolean prefixValid = (prefixPerm != null)
7965                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7966
7967            if (!(exactValid || prefixValid)) {
7968                throw new SecurityException("No persistable permission grants found for UID "
7969                        + callingUid + " and Uri " + grantUri.toSafeString());
7970            }
7971
7972            if (exactValid) {
7973                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7974            }
7975            if (prefixValid) {
7976                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7977            }
7978
7979            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7980
7981            if (persistChanged) {
7982                schedulePersistUriGrants();
7983            }
7984        }
7985    }
7986
7987    /**
7988     * @param uri This uri must NOT contain an embedded userId.
7989     * @param userId The userId in which the uri is to be resolved.
7990     */
7991    @Override
7992    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7993        enforceNotIsolatedCaller("releasePersistableUriPermission");
7994
7995        Preconditions.checkFlagsArgument(modeFlags,
7996                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7997
7998        synchronized (this) {
7999            final int callingUid = Binder.getCallingUid();
8000            boolean persistChanged = false;
8001
8002            UriPermission exactPerm = findUriPermissionLocked(callingUid,
8003                    new GrantUri(userId, uri, false));
8004            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8005                    new GrantUri(userId, uri, true));
8006            if (exactPerm == null && prefixPerm == null) {
8007                throw new SecurityException("No permission grants found for UID " + callingUid
8008                        + " and Uri " + uri.toSafeString());
8009            }
8010
8011            if (exactPerm != null) {
8012                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8013                removeUriPermissionIfNeededLocked(exactPerm);
8014            }
8015            if (prefixPerm != null) {
8016                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8017                removeUriPermissionIfNeededLocked(prefixPerm);
8018            }
8019
8020            if (persistChanged) {
8021                schedulePersistUriGrants();
8022            }
8023        }
8024    }
8025
8026    /**
8027     * Prune any older {@link UriPermission} for the given UID until outstanding
8028     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8029     *
8030     * @return if any mutations occured that require persisting.
8031     */
8032    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8033        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8034        if (perms == null) return false;
8035        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8036
8037        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8038        for (UriPermission perm : perms.values()) {
8039            if (perm.persistedModeFlags != 0) {
8040                persisted.add(perm);
8041            }
8042        }
8043
8044        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8045        if (trimCount <= 0) return false;
8046
8047        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8048        for (int i = 0; i < trimCount; i++) {
8049            final UriPermission perm = persisted.get(i);
8050
8051            if (DEBUG_URI_PERMISSION) {
8052                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8053            }
8054
8055            perm.releasePersistableModes(~0);
8056            removeUriPermissionIfNeededLocked(perm);
8057        }
8058
8059        return true;
8060    }
8061
8062    @Override
8063    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8064            String packageName, boolean incoming) {
8065        enforceNotIsolatedCaller("getPersistedUriPermissions");
8066        Preconditions.checkNotNull(packageName, "packageName");
8067
8068        final int callingUid = Binder.getCallingUid();
8069        final IPackageManager pm = AppGlobals.getPackageManager();
8070        try {
8071            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8072            if (packageUid != callingUid) {
8073                throw new SecurityException(
8074                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8075            }
8076        } catch (RemoteException e) {
8077            throw new SecurityException("Failed to verify package name ownership");
8078        }
8079
8080        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8081        synchronized (this) {
8082            if (incoming) {
8083                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8084                        callingUid);
8085                if (perms == null) {
8086                    Slog.w(TAG, "No permission grants found for " + packageName);
8087                } else {
8088                    for (UriPermission perm : perms.values()) {
8089                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8090                            result.add(perm.buildPersistedPublicApiObject());
8091                        }
8092                    }
8093                }
8094            } else {
8095                final int size = mGrantedUriPermissions.size();
8096                for (int i = 0; i < size; i++) {
8097                    final ArrayMap<GrantUri, UriPermission> perms =
8098                            mGrantedUriPermissions.valueAt(i);
8099                    for (UriPermission perm : perms.values()) {
8100                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8101                            result.add(perm.buildPersistedPublicApiObject());
8102                        }
8103                    }
8104                }
8105            }
8106        }
8107        return new ParceledListSlice<android.content.UriPermission>(result);
8108    }
8109
8110    @Override
8111    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8112        synchronized (this) {
8113            ProcessRecord app =
8114                who != null ? getRecordForAppLocked(who) : null;
8115            if (app == null) return;
8116
8117            Message msg = Message.obtain();
8118            msg.what = WAIT_FOR_DEBUGGER_MSG;
8119            msg.obj = app;
8120            msg.arg1 = waiting ? 1 : 0;
8121            mHandler.sendMessage(msg);
8122        }
8123    }
8124
8125    @Override
8126    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8127        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8128        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8129        outInfo.availMem = Process.getFreeMemory();
8130        outInfo.totalMem = Process.getTotalMemory();
8131        outInfo.threshold = homeAppMem;
8132        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8133        outInfo.hiddenAppThreshold = cachedAppMem;
8134        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8135                ProcessList.SERVICE_ADJ);
8136        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8137                ProcessList.VISIBLE_APP_ADJ);
8138        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8139                ProcessList.FOREGROUND_APP_ADJ);
8140    }
8141
8142    // =========================================================
8143    // TASK MANAGEMENT
8144    // =========================================================
8145
8146    @Override
8147    public List<IAppTask> getAppTasks(String callingPackage) {
8148        int callingUid = Binder.getCallingUid();
8149        long ident = Binder.clearCallingIdentity();
8150
8151        synchronized(this) {
8152            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8153            try {
8154                if (localLOGV) Slog.v(TAG, "getAppTasks");
8155
8156                final int N = mRecentTasks.size();
8157                for (int i = 0; i < N; i++) {
8158                    TaskRecord tr = mRecentTasks.get(i);
8159                    // Skip tasks that do not match the caller.  We don't need to verify
8160                    // callingPackage, because we are also limiting to callingUid and know
8161                    // that will limit to the correct security sandbox.
8162                    if (tr.effectiveUid != callingUid) {
8163                        continue;
8164                    }
8165                    Intent intent = tr.getBaseIntent();
8166                    if (intent == null ||
8167                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8168                        continue;
8169                    }
8170                    ActivityManager.RecentTaskInfo taskInfo =
8171                            createRecentTaskInfoFromTaskRecord(tr);
8172                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8173                    list.add(taskImpl);
8174                }
8175            } finally {
8176                Binder.restoreCallingIdentity(ident);
8177            }
8178            return list;
8179        }
8180    }
8181
8182    @Override
8183    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8184        final int callingUid = Binder.getCallingUid();
8185        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8186
8187        synchronized(this) {
8188            if (localLOGV) Slog.v(
8189                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8190
8191            final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8192                    callingUid);
8193
8194            // TODO: Improve with MRU list from all ActivityStacks.
8195            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8196        }
8197
8198        return list;
8199    }
8200
8201    TaskRecord getMostRecentTask() {
8202        return mRecentTasks.get(0);
8203    }
8204
8205    /**
8206     * Creates a new RecentTaskInfo from a TaskRecord.
8207     */
8208    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8209        // Update the task description to reflect any changes in the task stack
8210        tr.updateTaskDescription();
8211
8212        // Compose the recent task info
8213        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8214        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8215        rti.persistentId = tr.taskId;
8216        rti.baseIntent = new Intent(tr.getBaseIntent());
8217        rti.origActivity = tr.origActivity;
8218        rti.description = tr.lastDescription;
8219        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8220        rti.userId = tr.userId;
8221        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8222        rti.firstActiveTime = tr.firstActiveTime;
8223        rti.lastActiveTime = tr.lastActiveTime;
8224        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8225        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8226        return rti;
8227    }
8228
8229    private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8230        boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8231                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8232        if (!allowed) {
8233            if (checkPermission(android.Manifest.permission.GET_TASKS,
8234                    callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8235                // Temporary compatibility: some existing apps on the system image may
8236                // still be requesting the old permission and not switched to the new
8237                // one; if so, we'll still allow them full access.  This means we need
8238                // to see if they are holding the old permission and are a system app.
8239                try {
8240                    if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8241                        allowed = true;
8242                        Slog.w(TAG, caller + ": caller " + callingUid
8243                                + " is using old GET_TASKS but privileged; allowing");
8244                    }
8245                } catch (RemoteException e) {
8246                }
8247            }
8248        }
8249        if (!allowed) {
8250            Slog.w(TAG, caller + ": caller " + callingUid
8251                    + " does not hold GET_TASKS; limiting output");
8252        }
8253        return allowed;
8254    }
8255
8256    @Override
8257    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8258        final int callingUid = Binder.getCallingUid();
8259        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8260                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8261
8262        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8263        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8264        synchronized (this) {
8265            final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8266                    callingUid);
8267            final boolean detailed = checkCallingPermission(
8268                    android.Manifest.permission.GET_DETAILED_TASKS)
8269                    == PackageManager.PERMISSION_GRANTED;
8270
8271            final int N = mRecentTasks.size();
8272            ArrayList<ActivityManager.RecentTaskInfo> res
8273                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8274                            maxNum < N ? maxNum : N);
8275
8276            final Set<Integer> includedUsers;
8277            if (includeProfiles) {
8278                includedUsers = getProfileIdsLocked(userId);
8279            } else {
8280                includedUsers = new HashSet<Integer>();
8281            }
8282            includedUsers.add(Integer.valueOf(userId));
8283
8284            for (int i=0; i<N && maxNum > 0; i++) {
8285                TaskRecord tr = mRecentTasks.get(i);
8286                // Only add calling user or related users recent tasks
8287                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8288                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8289                    continue;
8290                }
8291
8292                // Return the entry if desired by the caller.  We always return
8293                // the first entry, because callers always expect this to be the
8294                // foreground app.  We may filter others if the caller has
8295                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8296                // we should exclude the entry.
8297
8298                if (i == 0
8299                        || withExcluded
8300                        || (tr.intent == null)
8301                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8302                                == 0)) {
8303                    if (!allowed) {
8304                        // If the caller doesn't have the GET_TASKS permission, then only
8305                        // allow them to see a small subset of tasks -- their own and home.
8306                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8307                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8308                            continue;
8309                        }
8310                    }
8311                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8312                        if (tr.stack != null && tr.stack.isHomeStack()) {
8313                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8314                            continue;
8315                        }
8316                    }
8317                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8318                        // Don't include auto remove tasks that are finished or finishing.
8319                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8320                                + tr);
8321                        continue;
8322                    }
8323                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8324                            && !tr.isAvailable) {
8325                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8326                        continue;
8327                    }
8328
8329                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8330                    if (!detailed) {
8331                        rti.baseIntent.replaceExtras((Bundle)null);
8332                    }
8333
8334                    res.add(rti);
8335                    maxNum--;
8336                }
8337            }
8338            return res;
8339        }
8340    }
8341
8342    private TaskRecord recentTaskForIdLocked(int id) {
8343        final int N = mRecentTasks.size();
8344            for (int i=0; i<N; i++) {
8345                TaskRecord tr = mRecentTasks.get(i);
8346                if (tr.taskId == id) {
8347                    return tr;
8348                }
8349            }
8350            return null;
8351    }
8352
8353    @Override
8354    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8355        synchronized (this) {
8356            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8357                    "getTaskThumbnail()");
8358            TaskRecord tr = recentTaskForIdLocked(id);
8359            if (tr != null) {
8360                return tr.getTaskThumbnailLocked();
8361            }
8362        }
8363        return null;
8364    }
8365
8366    @Override
8367    public int addAppTask(IBinder activityToken, Intent intent,
8368            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8369        final int callingUid = Binder.getCallingUid();
8370        final long callingIdent = Binder.clearCallingIdentity();
8371
8372        try {
8373            synchronized (this) {
8374                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8375                if (r == null) {
8376                    throw new IllegalArgumentException("Activity does not exist; token="
8377                            + activityToken);
8378                }
8379                ComponentName comp = intent.getComponent();
8380                if (comp == null) {
8381                    throw new IllegalArgumentException("Intent " + intent
8382                            + " must specify explicit component");
8383                }
8384                if (thumbnail.getWidth() != mThumbnailWidth
8385                        || thumbnail.getHeight() != mThumbnailHeight) {
8386                    throw new IllegalArgumentException("Bad thumbnail size: got "
8387                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8388                            + mThumbnailWidth + "x" + mThumbnailHeight);
8389                }
8390                if (intent.getSelector() != null) {
8391                    intent.setSelector(null);
8392                }
8393                if (intent.getSourceBounds() != null) {
8394                    intent.setSourceBounds(null);
8395                }
8396                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8397                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8398                        // The caller has added this as an auto-remove task...  that makes no
8399                        // sense, so turn off auto-remove.
8400                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8401                    }
8402                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8403                    // Must be a new task.
8404                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8405                }
8406                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8407                    mLastAddedTaskActivity = null;
8408                }
8409                ActivityInfo ainfo = mLastAddedTaskActivity;
8410                if (ainfo == null) {
8411                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8412                            comp, 0, UserHandle.getUserId(callingUid));
8413                    if (ainfo.applicationInfo.uid != callingUid) {
8414                        throw new SecurityException(
8415                                "Can't add task for another application: target uid="
8416                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8417                    }
8418                }
8419
8420                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8421                        intent, description);
8422
8423                int trimIdx = trimRecentsForTask(task, false);
8424                if (trimIdx >= 0) {
8425                    // If this would have caused a trim, then we'll abort because that
8426                    // means it would be added at the end of the list but then just removed.
8427                    return -1;
8428                }
8429
8430                final int N = mRecentTasks.size();
8431                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8432                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8433                    tr.removedFromRecents(mTaskPersister);
8434                }
8435
8436                task.inRecents = true;
8437                mRecentTasks.add(task);
8438                r.task.stack.addTask(task, false, false);
8439
8440                task.setLastThumbnail(thumbnail);
8441                task.freeLastThumbnail();
8442
8443                return task.taskId;
8444            }
8445        } finally {
8446            Binder.restoreCallingIdentity(callingIdent);
8447        }
8448    }
8449
8450    @Override
8451    public Point getAppTaskThumbnailSize() {
8452        synchronized (this) {
8453            return new Point(mThumbnailWidth,  mThumbnailHeight);
8454        }
8455    }
8456
8457    @Override
8458    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8459        synchronized (this) {
8460            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8461            if (r != null) {
8462                r.setTaskDescription(td);
8463                r.task.updateTaskDescription();
8464            }
8465        }
8466    }
8467
8468    @Override
8469    public Bitmap getTaskDescriptionIcon(String filename) {
8470        if (!FileUtils.isValidExtFilename(filename)
8471                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8472            throw new IllegalArgumentException("Bad filename: " + filename);
8473        }
8474        return mTaskPersister.getTaskDescriptionIcon(filename);
8475    }
8476
8477    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8478        mRecentTasks.remove(tr);
8479        tr.removedFromRecents(mTaskPersister);
8480        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8481        Intent baseIntent = new Intent(
8482                tr.intent != null ? tr.intent : tr.affinityIntent);
8483        ComponentName component = baseIntent.getComponent();
8484        if (component == null) {
8485            Slog.w(TAG, "Now component for base intent of task: " + tr);
8486            return;
8487        }
8488
8489        // Find any running services associated with this app.
8490        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8491
8492        if (killProcesses) {
8493            // Find any running processes associated with this app.
8494            final String pkg = component.getPackageName();
8495            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8496            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8497            for (int i=0; i<pmap.size(); i++) {
8498                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8499                for (int j=0; j<uids.size(); j++) {
8500                    ProcessRecord proc = uids.valueAt(j);
8501                    if (proc.userId != tr.userId) {
8502                        continue;
8503                    }
8504                    if (!proc.pkgList.containsKey(pkg)) {
8505                        continue;
8506                    }
8507                    procs.add(proc);
8508                }
8509            }
8510
8511            // Kill the running processes.
8512            for (int i=0; i<procs.size(); i++) {
8513                ProcessRecord pr = procs.get(i);
8514                if (pr == mHomeProcess) {
8515                    // Don't kill the home process along with tasks from the same package.
8516                    continue;
8517                }
8518                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8519                    pr.kill("remove task", true);
8520                } else {
8521                    pr.waitingToKill = "remove task";
8522                }
8523            }
8524        }
8525    }
8526
8527    /**
8528     * Removes the task with the specified task id.
8529     *
8530     * @param taskId Identifier of the task to be removed.
8531     * @param flags Additional operational flags.  May be 0 or
8532     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8533     * @return Returns true if the given task was found and removed.
8534     */
8535    private boolean removeTaskByIdLocked(int taskId, int flags) {
8536        TaskRecord tr = recentTaskForIdLocked(taskId);
8537        if (tr != null) {
8538            tr.removeTaskActivitiesLocked();
8539            cleanUpRemovedTaskLocked(tr, flags);
8540            if (tr.isPersistable) {
8541                notifyTaskPersisterLocked(null, true);
8542            }
8543            return true;
8544        }
8545        return false;
8546    }
8547
8548    @Override
8549    public boolean removeTask(int taskId, int flags) {
8550        synchronized (this) {
8551            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8552                    "removeTask()");
8553            long ident = Binder.clearCallingIdentity();
8554            try {
8555                return removeTaskByIdLocked(taskId, flags);
8556            } finally {
8557                Binder.restoreCallingIdentity(ident);
8558            }
8559        }
8560    }
8561
8562    /**
8563     * TODO: Add mController hook
8564     */
8565    @Override
8566    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8567        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8568                "moveTaskToFront()");
8569
8570        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8571        synchronized(this) {
8572            moveTaskToFrontLocked(taskId, flags, options);
8573        }
8574    }
8575
8576    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8577        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8578                Binder.getCallingUid(), -1, -1, "Task to front")) {
8579            ActivityOptions.abort(options);
8580            return;
8581        }
8582        final long origId = Binder.clearCallingIdentity();
8583        try {
8584            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8585            if (task == null) {
8586                return;
8587            }
8588            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8589                mStackSupervisor.showLockTaskToast();
8590                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8591                return;
8592            }
8593            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8594            if (prev != null && prev.isRecentsActivity()) {
8595                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8596            }
8597            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8598        } finally {
8599            Binder.restoreCallingIdentity(origId);
8600        }
8601        ActivityOptions.abort(options);
8602    }
8603
8604    @Override
8605    public void moveTaskToBack(int taskId) {
8606        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8607                "moveTaskToBack()");
8608
8609        synchronized(this) {
8610            TaskRecord tr = recentTaskForIdLocked(taskId);
8611            if (tr != null) {
8612                if (tr == mStackSupervisor.mLockTaskModeTask) {
8613                    mStackSupervisor.showLockTaskToast();
8614                    return;
8615                }
8616                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8617                ActivityStack stack = tr.stack;
8618                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8619                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8620                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8621                        return;
8622                    }
8623                }
8624                final long origId = Binder.clearCallingIdentity();
8625                try {
8626                    stack.moveTaskToBackLocked(taskId, null);
8627                } finally {
8628                    Binder.restoreCallingIdentity(origId);
8629                }
8630            }
8631        }
8632    }
8633
8634    /**
8635     * Moves an activity, and all of the other activities within the same task, to the bottom
8636     * of the history stack.  The activity's order within the task is unchanged.
8637     *
8638     * @param token A reference to the activity we wish to move
8639     * @param nonRoot If false then this only works if the activity is the root
8640     *                of a task; if true it will work for any activity in a task.
8641     * @return Returns true if the move completed, false if not.
8642     */
8643    @Override
8644    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8645        enforceNotIsolatedCaller("moveActivityTaskToBack");
8646        synchronized(this) {
8647            final long origId = Binder.clearCallingIdentity();
8648            try {
8649                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8650                if (taskId >= 0) {
8651                    if ((mStackSupervisor.mLockTaskModeTask != null)
8652                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8653                        mStackSupervisor.showLockTaskToast();
8654                        return false;
8655                    }
8656                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8657                }
8658            } finally {
8659                Binder.restoreCallingIdentity(origId);
8660            }
8661        }
8662        return false;
8663    }
8664
8665    @Override
8666    public void moveTaskBackwards(int task) {
8667        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8668                "moveTaskBackwards()");
8669
8670        synchronized(this) {
8671            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8672                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8673                return;
8674            }
8675            final long origId = Binder.clearCallingIdentity();
8676            moveTaskBackwardsLocked(task);
8677            Binder.restoreCallingIdentity(origId);
8678        }
8679    }
8680
8681    private final void moveTaskBackwardsLocked(int task) {
8682        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8683    }
8684
8685    @Override
8686    public IBinder getHomeActivityToken() throws RemoteException {
8687        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8688                "getHomeActivityToken()");
8689        synchronized (this) {
8690            return mStackSupervisor.getHomeActivityToken();
8691        }
8692    }
8693
8694    @Override
8695    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8696            IActivityContainerCallback callback) throws RemoteException {
8697        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8698                "createActivityContainer()");
8699        synchronized (this) {
8700            if (parentActivityToken == null) {
8701                throw new IllegalArgumentException("parent token must not be null");
8702            }
8703            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8704            if (r == null) {
8705                return null;
8706            }
8707            if (callback == null) {
8708                throw new IllegalArgumentException("callback must not be null");
8709            }
8710            return mStackSupervisor.createActivityContainer(r, callback);
8711        }
8712    }
8713
8714    @Override
8715    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8716        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8717                "deleteActivityContainer()");
8718        synchronized (this) {
8719            mStackSupervisor.deleteActivityContainer(container);
8720        }
8721    }
8722
8723    @Override
8724    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8725            throws RemoteException {
8726        synchronized (this) {
8727            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8728            if (stack != null) {
8729                return stack.mActivityContainer;
8730            }
8731            return null;
8732        }
8733    }
8734
8735    @Override
8736    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8737        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8738                "moveTaskToStack()");
8739        if (stackId == HOME_STACK_ID) {
8740            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8741                    new RuntimeException("here").fillInStackTrace());
8742        }
8743        synchronized (this) {
8744            long ident = Binder.clearCallingIdentity();
8745            try {
8746                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8747                        + stackId + " toTop=" + toTop);
8748                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8749            } finally {
8750                Binder.restoreCallingIdentity(ident);
8751            }
8752        }
8753    }
8754
8755    @Override
8756    public void resizeStack(int stackBoxId, Rect bounds) {
8757        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8758                "resizeStackBox()");
8759        long ident = Binder.clearCallingIdentity();
8760        try {
8761            mWindowManager.resizeStack(stackBoxId, bounds);
8762        } finally {
8763            Binder.restoreCallingIdentity(ident);
8764        }
8765    }
8766
8767    @Override
8768    public List<StackInfo> getAllStackInfos() {
8769        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8770                "getAllStackInfos()");
8771        long ident = Binder.clearCallingIdentity();
8772        try {
8773            synchronized (this) {
8774                return mStackSupervisor.getAllStackInfosLocked();
8775            }
8776        } finally {
8777            Binder.restoreCallingIdentity(ident);
8778        }
8779    }
8780
8781    @Override
8782    public StackInfo getStackInfo(int stackId) {
8783        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8784                "getStackInfo()");
8785        long ident = Binder.clearCallingIdentity();
8786        try {
8787            synchronized (this) {
8788                return mStackSupervisor.getStackInfoLocked(stackId);
8789            }
8790        } finally {
8791            Binder.restoreCallingIdentity(ident);
8792        }
8793    }
8794
8795    @Override
8796    public boolean isInHomeStack(int taskId) {
8797        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8798                "getStackInfo()");
8799        long ident = Binder.clearCallingIdentity();
8800        try {
8801            synchronized (this) {
8802                TaskRecord tr = recentTaskForIdLocked(taskId);
8803                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8804            }
8805        } finally {
8806            Binder.restoreCallingIdentity(ident);
8807        }
8808    }
8809
8810    @Override
8811    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8812        synchronized(this) {
8813            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8814        }
8815    }
8816
8817    private boolean isLockTaskAuthorized(String pkg) {
8818        final DevicePolicyManager dpm = (DevicePolicyManager)
8819                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8820        try {
8821            int uid = mContext.getPackageManager().getPackageUid(pkg,
8822                    Binder.getCallingUserHandle().getIdentifier());
8823            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8824        } catch (NameNotFoundException e) {
8825            return false;
8826        }
8827    }
8828
8829    void startLockTaskMode(TaskRecord task) {
8830        final String pkg;
8831        synchronized (this) {
8832            pkg = task.intent.getComponent().getPackageName();
8833        }
8834        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8835        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8836            final TaskRecord taskRecord = task;
8837            mHandler.post(new Runnable() {
8838                @Override
8839                public void run() {
8840                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8841                }
8842            });
8843            return;
8844        }
8845        long ident = Binder.clearCallingIdentity();
8846        try {
8847            synchronized (this) {
8848                // Since we lost lock on task, make sure it is still there.
8849                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8850                if (task != null) {
8851                    if (!isSystemInitiated
8852                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8853                        throw new IllegalArgumentException("Invalid task, not in foreground");
8854                    }
8855                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8856                }
8857            }
8858        } finally {
8859            Binder.restoreCallingIdentity(ident);
8860        }
8861    }
8862
8863    @Override
8864    public void startLockTaskMode(int taskId) {
8865        final TaskRecord task;
8866        long ident = Binder.clearCallingIdentity();
8867        try {
8868            synchronized (this) {
8869                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8870            }
8871        } finally {
8872            Binder.restoreCallingIdentity(ident);
8873        }
8874        if (task != null) {
8875            startLockTaskMode(task);
8876        }
8877    }
8878
8879    @Override
8880    public void startLockTaskMode(IBinder token) {
8881        final TaskRecord task;
8882        long ident = Binder.clearCallingIdentity();
8883        try {
8884            synchronized (this) {
8885                final ActivityRecord r = ActivityRecord.forToken(token);
8886                if (r == null) {
8887                    return;
8888                }
8889                task = r.task;
8890            }
8891        } finally {
8892            Binder.restoreCallingIdentity(ident);
8893        }
8894        if (task != null) {
8895            startLockTaskMode(task);
8896        }
8897    }
8898
8899    @Override
8900    public void startLockTaskModeOnCurrent() throws RemoteException {
8901        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8902                "startLockTaskModeOnCurrent");
8903        ActivityRecord r = null;
8904        synchronized (this) {
8905            r = mStackSupervisor.topRunningActivityLocked();
8906        }
8907        startLockTaskMode(r.task);
8908    }
8909
8910    @Override
8911    public void stopLockTaskMode() {
8912        // Verify that the user matches the package of the intent for the TaskRecord
8913        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8914        // and stopLockTaskMode.
8915        final int callingUid = Binder.getCallingUid();
8916        if (callingUid != Process.SYSTEM_UID) {
8917            try {
8918                String pkg =
8919                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8920                int uid = mContext.getPackageManager().getPackageUid(pkg,
8921                        Binder.getCallingUserHandle().getIdentifier());
8922                if (uid != callingUid) {
8923                    throw new SecurityException("Invalid uid, expected " + uid);
8924                }
8925            } catch (NameNotFoundException e) {
8926                Log.d(TAG, "stopLockTaskMode " + e);
8927                return;
8928            }
8929        }
8930        long ident = Binder.clearCallingIdentity();
8931        try {
8932            Log.d(TAG, "stopLockTaskMode");
8933            // Stop lock task
8934            synchronized (this) {
8935                mStackSupervisor.setLockTaskModeLocked(null, false);
8936            }
8937        } finally {
8938            Binder.restoreCallingIdentity(ident);
8939        }
8940    }
8941
8942    @Override
8943    public void stopLockTaskModeOnCurrent() throws RemoteException {
8944        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8945                "stopLockTaskModeOnCurrent");
8946        long ident = Binder.clearCallingIdentity();
8947        try {
8948            stopLockTaskMode();
8949        } finally {
8950            Binder.restoreCallingIdentity(ident);
8951        }
8952    }
8953
8954    @Override
8955    public boolean isInLockTaskMode() {
8956        synchronized (this) {
8957            return mStackSupervisor.isInLockTaskMode();
8958        }
8959    }
8960
8961    // =========================================================
8962    // CONTENT PROVIDERS
8963    // =========================================================
8964
8965    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8966        List<ProviderInfo> providers = null;
8967        try {
8968            providers = AppGlobals.getPackageManager().
8969                queryContentProviders(app.processName, app.uid,
8970                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8971        } catch (RemoteException ex) {
8972        }
8973        if (DEBUG_MU)
8974            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8975        int userId = app.userId;
8976        if (providers != null) {
8977            int N = providers.size();
8978            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8979            for (int i=0; i<N; i++) {
8980                ProviderInfo cpi =
8981                    (ProviderInfo)providers.get(i);
8982                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8983                        cpi.name, cpi.flags);
8984                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8985                    // This is a singleton provider, but a user besides the
8986                    // default user is asking to initialize a process it runs
8987                    // in...  well, no, it doesn't actually run in this process,
8988                    // it runs in the process of the default user.  Get rid of it.
8989                    providers.remove(i);
8990                    N--;
8991                    i--;
8992                    continue;
8993                }
8994
8995                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8996                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8997                if (cpr == null) {
8998                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8999                    mProviderMap.putProviderByClass(comp, cpr);
9000                }
9001                if (DEBUG_MU)
9002                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9003                app.pubProviders.put(cpi.name, cpr);
9004                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9005                    // Don't add this if it is a platform component that is marked
9006                    // to run in multiple processes, because this is actually
9007                    // part of the framework so doesn't make sense to track as a
9008                    // separate apk in the process.
9009                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9010                            mProcessStats);
9011                }
9012                ensurePackageDexOpt(cpi.applicationInfo.packageName);
9013            }
9014        }
9015        return providers;
9016    }
9017
9018    /**
9019     * Check if {@link ProcessRecord} has a possible chance at accessing the
9020     * given {@link ProviderInfo}. Final permission checking is always done
9021     * in {@link ContentProvider}.
9022     */
9023    private final String checkContentProviderPermissionLocked(
9024            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9025        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9026        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9027        boolean checkedGrants = false;
9028        if (checkUser) {
9029            // Looking for cross-user grants before enforcing the typical cross-users permissions
9030            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9031            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9032                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9033                    return null;
9034                }
9035                checkedGrants = true;
9036            }
9037            userId = handleIncomingUser(callingPid, callingUid, userId,
9038                    false, ALLOW_NON_FULL,
9039                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9040            if (userId != tmpTargetUserId) {
9041                // When we actually went to determine the final targer user ID, this ended
9042                // up different than our initial check for the authority.  This is because
9043                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9044                // SELF.  So we need to re-check the grants again.
9045                checkedGrants = false;
9046            }
9047        }
9048        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9049                cpi.applicationInfo.uid, cpi.exported)
9050                == PackageManager.PERMISSION_GRANTED) {
9051            return null;
9052        }
9053        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9054                cpi.applicationInfo.uid, cpi.exported)
9055                == PackageManager.PERMISSION_GRANTED) {
9056            return null;
9057        }
9058
9059        PathPermission[] pps = cpi.pathPermissions;
9060        if (pps != null) {
9061            int i = pps.length;
9062            while (i > 0) {
9063                i--;
9064                PathPermission pp = pps[i];
9065                String pprperm = pp.getReadPermission();
9066                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9067                        cpi.applicationInfo.uid, cpi.exported)
9068                        == PackageManager.PERMISSION_GRANTED) {
9069                    return null;
9070                }
9071                String ppwperm = pp.getWritePermission();
9072                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9073                        cpi.applicationInfo.uid, cpi.exported)
9074                        == PackageManager.PERMISSION_GRANTED) {
9075                    return null;
9076                }
9077            }
9078        }
9079        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9080            return null;
9081        }
9082
9083        String msg;
9084        if (!cpi.exported) {
9085            msg = "Permission Denial: opening provider " + cpi.name
9086                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9087                    + ", uid=" + callingUid + ") that is not exported from uid "
9088                    + cpi.applicationInfo.uid;
9089        } else {
9090            msg = "Permission Denial: opening provider " + cpi.name
9091                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9092                    + ", uid=" + callingUid + ") requires "
9093                    + cpi.readPermission + " or " + cpi.writePermission;
9094        }
9095        Slog.w(TAG, msg);
9096        return msg;
9097    }
9098
9099    /**
9100     * Returns if the ContentProvider has granted a uri to callingUid
9101     */
9102    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9103        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9104        if (perms != null) {
9105            for (int i=perms.size()-1; i>=0; i--) {
9106                GrantUri grantUri = perms.keyAt(i);
9107                if (grantUri.sourceUserId == userId || !checkUser) {
9108                    if (matchesProvider(grantUri.uri, cpi)) {
9109                        return true;
9110                    }
9111                }
9112            }
9113        }
9114        return false;
9115    }
9116
9117    /**
9118     * Returns true if the uri authority is one of the authorities specified in the provider.
9119     */
9120    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9121        String uriAuth = uri.getAuthority();
9122        String cpiAuth = cpi.authority;
9123        if (cpiAuth.indexOf(';') == -1) {
9124            return cpiAuth.equals(uriAuth);
9125        }
9126        String[] cpiAuths = cpiAuth.split(";");
9127        int length = cpiAuths.length;
9128        for (int i = 0; i < length; i++) {
9129            if (cpiAuths[i].equals(uriAuth)) return true;
9130        }
9131        return false;
9132    }
9133
9134    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9135            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9136        if (r != null) {
9137            for (int i=0; i<r.conProviders.size(); i++) {
9138                ContentProviderConnection conn = r.conProviders.get(i);
9139                if (conn.provider == cpr) {
9140                    if (DEBUG_PROVIDER) Slog.v(TAG,
9141                            "Adding provider requested by "
9142                            + r.processName + " from process "
9143                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9144                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9145                    if (stable) {
9146                        conn.stableCount++;
9147                        conn.numStableIncs++;
9148                    } else {
9149                        conn.unstableCount++;
9150                        conn.numUnstableIncs++;
9151                    }
9152                    return conn;
9153                }
9154            }
9155            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9156            if (stable) {
9157                conn.stableCount = 1;
9158                conn.numStableIncs = 1;
9159            } else {
9160                conn.unstableCount = 1;
9161                conn.numUnstableIncs = 1;
9162            }
9163            cpr.connections.add(conn);
9164            r.conProviders.add(conn);
9165            return conn;
9166        }
9167        cpr.addExternalProcessHandleLocked(externalProcessToken);
9168        return null;
9169    }
9170
9171    boolean decProviderCountLocked(ContentProviderConnection conn,
9172            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9173        if (conn != null) {
9174            cpr = conn.provider;
9175            if (DEBUG_PROVIDER) Slog.v(TAG,
9176                    "Removing provider requested by "
9177                    + conn.client.processName + " from process "
9178                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9179                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9180            if (stable) {
9181                conn.stableCount--;
9182            } else {
9183                conn.unstableCount--;
9184            }
9185            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9186                cpr.connections.remove(conn);
9187                conn.client.conProviders.remove(conn);
9188                return true;
9189            }
9190            return false;
9191        }
9192        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9193        return false;
9194    }
9195
9196    private void checkTime(long startTime, String where) {
9197        long now = SystemClock.elapsedRealtime();
9198        if ((now-startTime) > 1000) {
9199            // If we are taking more than a second, log about it.
9200            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9201        }
9202    }
9203
9204    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9205            String name, IBinder token, boolean stable, int userId) {
9206        ContentProviderRecord cpr;
9207        ContentProviderConnection conn = null;
9208        ProviderInfo cpi = null;
9209
9210        synchronized(this) {
9211            long startTime = SystemClock.elapsedRealtime();
9212
9213            ProcessRecord r = null;
9214            if (caller != null) {
9215                r = getRecordForAppLocked(caller);
9216                if (r == null) {
9217                    throw new SecurityException(
9218                            "Unable to find app for caller " + caller
9219                          + " (pid=" + Binder.getCallingPid()
9220                          + ") when getting content provider " + name);
9221                }
9222            }
9223
9224            boolean checkCrossUser = true;
9225
9226            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9227
9228            // First check if this content provider has been published...
9229            cpr = mProviderMap.getProviderByName(name, userId);
9230            // If that didn't work, check if it exists for user 0 and then
9231            // verify that it's a singleton provider before using it.
9232            if (cpr == null && userId != UserHandle.USER_OWNER) {
9233                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9234                if (cpr != null) {
9235                    cpi = cpr.info;
9236                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9237                            cpi.name, cpi.flags)
9238                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9239                        userId = UserHandle.USER_OWNER;
9240                        checkCrossUser = false;
9241                    } else {
9242                        cpr = null;
9243                        cpi = null;
9244                    }
9245                }
9246            }
9247
9248            boolean providerRunning = cpr != null;
9249            if (providerRunning) {
9250                cpi = cpr.info;
9251                String msg;
9252                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9253                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9254                        != null) {
9255                    throw new SecurityException(msg);
9256                }
9257                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9258
9259                if (r != null && cpr.canRunHere(r)) {
9260                    // This provider has been published or is in the process
9261                    // of being published...  but it is also allowed to run
9262                    // in the caller's process, so don't make a connection
9263                    // and just let the caller instantiate its own instance.
9264                    ContentProviderHolder holder = cpr.newHolder(null);
9265                    // don't give caller the provider object, it needs
9266                    // to make its own.
9267                    holder.provider = null;
9268                    return holder;
9269                }
9270
9271                final long origId = Binder.clearCallingIdentity();
9272
9273                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9274
9275                // In this case the provider instance already exists, so we can
9276                // return it right away.
9277                conn = incProviderCountLocked(r, cpr, token, stable);
9278                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9279                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9280                        // If this is a perceptible app accessing the provider,
9281                        // make sure to count it as being accessed and thus
9282                        // back up on the LRU list.  This is good because
9283                        // content providers are often expensive to start.
9284                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9285                        updateLruProcessLocked(cpr.proc, false, null);
9286                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9287                    }
9288                }
9289
9290                if (cpr.proc != null) {
9291                    if (false) {
9292                        if (cpr.name.flattenToShortString().equals(
9293                                "com.android.providers.calendar/.CalendarProvider2")) {
9294                            Slog.v(TAG, "****************** KILLING "
9295                                + cpr.name.flattenToShortString());
9296                            Process.killProcess(cpr.proc.pid);
9297                        }
9298                    }
9299                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9300                    boolean success = updateOomAdjLocked(cpr.proc);
9301                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9302                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9303                    // NOTE: there is still a race here where a signal could be
9304                    // pending on the process even though we managed to update its
9305                    // adj level.  Not sure what to do about this, but at least
9306                    // the race is now smaller.
9307                    if (!success) {
9308                        // Uh oh...  it looks like the provider's process
9309                        // has been killed on us.  We need to wait for a new
9310                        // process to be started, and make sure its death
9311                        // doesn't kill our process.
9312                        Slog.i(TAG,
9313                                "Existing provider " + cpr.name.flattenToShortString()
9314                                + " is crashing; detaching " + r);
9315                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9316                        checkTime(startTime, "getContentProviderImpl: before appDied");
9317                        appDiedLocked(cpr.proc);
9318                        checkTime(startTime, "getContentProviderImpl: after appDied");
9319                        if (!lastRef) {
9320                            // This wasn't the last ref our process had on
9321                            // the provider...  we have now been killed, bail.
9322                            return null;
9323                        }
9324                        providerRunning = false;
9325                        conn = null;
9326                    }
9327                }
9328
9329                Binder.restoreCallingIdentity(origId);
9330            }
9331
9332            boolean singleton;
9333            if (!providerRunning) {
9334                try {
9335                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9336                    cpi = AppGlobals.getPackageManager().
9337                        resolveContentProvider(name,
9338                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9339                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9340                } catch (RemoteException ex) {
9341                }
9342                if (cpi == null) {
9343                    return null;
9344                }
9345                // If the provider is a singleton AND
9346                // (it's a call within the same user || the provider is a
9347                // privileged app)
9348                // Then allow connecting to the singleton provider
9349                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9350                        cpi.name, cpi.flags)
9351                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9352                if (singleton) {
9353                    userId = UserHandle.USER_OWNER;
9354                }
9355                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9356                checkTime(startTime, "getContentProviderImpl: got app info for user");
9357
9358                String msg;
9359                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9360                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9361                        != null) {
9362                    throw new SecurityException(msg);
9363                }
9364                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9365
9366                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9367                        && !cpi.processName.equals("system")) {
9368                    // If this content provider does not run in the system
9369                    // process, and the system is not yet ready to run other
9370                    // processes, then fail fast instead of hanging.
9371                    throw new IllegalArgumentException(
9372                            "Attempt to launch content provider before system ready");
9373                }
9374
9375                // Make sure that the user who owns this provider is started.  If not,
9376                // we don't want to allow it to run.
9377                if (mStartedUsers.get(userId) == null) {
9378                    Slog.w(TAG, "Unable to launch app "
9379                            + cpi.applicationInfo.packageName + "/"
9380                            + cpi.applicationInfo.uid + " for provider "
9381                            + name + ": user " + userId + " is stopped");
9382                    return null;
9383                }
9384
9385                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9386                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9387                cpr = mProviderMap.getProviderByClass(comp, userId);
9388                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9389                final boolean firstClass = cpr == null;
9390                if (firstClass) {
9391                    final long ident = Binder.clearCallingIdentity();
9392                    try {
9393                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9394                        ApplicationInfo ai =
9395                            AppGlobals.getPackageManager().
9396                                getApplicationInfo(
9397                                        cpi.applicationInfo.packageName,
9398                                        STOCK_PM_FLAGS, userId);
9399                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9400                        if (ai == null) {
9401                            Slog.w(TAG, "No package info for content provider "
9402                                    + cpi.name);
9403                            return null;
9404                        }
9405                        ai = getAppInfoForUser(ai, userId);
9406                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9407                    } catch (RemoteException ex) {
9408                        // pm is in same process, this will never happen.
9409                    } finally {
9410                        Binder.restoreCallingIdentity(ident);
9411                    }
9412                }
9413
9414                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9415
9416                if (r != null && cpr.canRunHere(r)) {
9417                    // If this is a multiprocess provider, then just return its
9418                    // info and allow the caller to instantiate it.  Only do
9419                    // this if the provider is the same user as the caller's
9420                    // process, or can run as root (so can be in any process).
9421                    return cpr.newHolder(null);
9422                }
9423
9424                if (DEBUG_PROVIDER) {
9425                    RuntimeException e = new RuntimeException("here");
9426                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9427                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9428                }
9429
9430                // This is single process, and our app is now connecting to it.
9431                // See if we are already in the process of launching this
9432                // provider.
9433                final int N = mLaunchingProviders.size();
9434                int i;
9435                for (i=0; i<N; i++) {
9436                    if (mLaunchingProviders.get(i) == cpr) {
9437                        break;
9438                    }
9439                }
9440
9441                // If the provider is not already being launched, then get it
9442                // started.
9443                if (i >= N) {
9444                    final long origId = Binder.clearCallingIdentity();
9445
9446                    try {
9447                        // Content provider is now in use, its package can't be stopped.
9448                        try {
9449                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9450                            AppGlobals.getPackageManager().setPackageStoppedState(
9451                                    cpr.appInfo.packageName, false, userId);
9452                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9453                        } catch (RemoteException e) {
9454                        } catch (IllegalArgumentException e) {
9455                            Slog.w(TAG, "Failed trying to unstop package "
9456                                    + cpr.appInfo.packageName + ": " + e);
9457                        }
9458
9459                        // Use existing process if already started
9460                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9461                        ProcessRecord proc = getProcessRecordLocked(
9462                                cpi.processName, cpr.appInfo.uid, false);
9463                        if (proc != null && proc.thread != null) {
9464                            if (DEBUG_PROVIDER) {
9465                                Slog.d(TAG, "Installing in existing process " + proc);
9466                            }
9467                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9468                            proc.pubProviders.put(cpi.name, cpr);
9469                            try {
9470                                proc.thread.scheduleInstallProvider(cpi);
9471                            } catch (RemoteException e) {
9472                            }
9473                        } else {
9474                            checkTime(startTime, "getContentProviderImpl: before start process");
9475                            proc = startProcessLocked(cpi.processName,
9476                                    cpr.appInfo, false, 0, "content provider",
9477                                    new ComponentName(cpi.applicationInfo.packageName,
9478                                            cpi.name), false, false, false);
9479                            checkTime(startTime, "getContentProviderImpl: after start process");
9480                            if (proc == null) {
9481                                Slog.w(TAG, "Unable to launch app "
9482                                        + cpi.applicationInfo.packageName + "/"
9483                                        + cpi.applicationInfo.uid + " for provider "
9484                                        + name + ": process is bad");
9485                                return null;
9486                            }
9487                        }
9488                        cpr.launchingApp = proc;
9489                        mLaunchingProviders.add(cpr);
9490                    } finally {
9491                        Binder.restoreCallingIdentity(origId);
9492                    }
9493                }
9494
9495                checkTime(startTime, "getContentProviderImpl: updating data structures");
9496
9497                // Make sure the provider is published (the same provider class
9498                // may be published under multiple names).
9499                if (firstClass) {
9500                    mProviderMap.putProviderByClass(comp, cpr);
9501                }
9502
9503                mProviderMap.putProviderByName(name, cpr);
9504                conn = incProviderCountLocked(r, cpr, token, stable);
9505                if (conn != null) {
9506                    conn.waiting = true;
9507                }
9508            }
9509            checkTime(startTime, "getContentProviderImpl: done!");
9510        }
9511
9512        // Wait for the provider to be published...
9513        synchronized (cpr) {
9514            while (cpr.provider == null) {
9515                if (cpr.launchingApp == null) {
9516                    Slog.w(TAG, "Unable to launch app "
9517                            + cpi.applicationInfo.packageName + "/"
9518                            + cpi.applicationInfo.uid + " for provider "
9519                            + name + ": launching app became null");
9520                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9521                            UserHandle.getUserId(cpi.applicationInfo.uid),
9522                            cpi.applicationInfo.packageName,
9523                            cpi.applicationInfo.uid, name);
9524                    return null;
9525                }
9526                try {
9527                    if (DEBUG_MU) {
9528                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9529                                + cpr.launchingApp);
9530                    }
9531                    if (conn != null) {
9532                        conn.waiting = true;
9533                    }
9534                    cpr.wait();
9535                } catch (InterruptedException ex) {
9536                } finally {
9537                    if (conn != null) {
9538                        conn.waiting = false;
9539                    }
9540                }
9541            }
9542        }
9543        return cpr != null ? cpr.newHolder(conn) : null;
9544    }
9545
9546    @Override
9547    public final ContentProviderHolder getContentProvider(
9548            IApplicationThread caller, String name, int userId, boolean stable) {
9549        enforceNotIsolatedCaller("getContentProvider");
9550        if (caller == null) {
9551            String msg = "null IApplicationThread when getting content provider "
9552                    + name;
9553            Slog.w(TAG, msg);
9554            throw new SecurityException(msg);
9555        }
9556        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9557        // with cross-user grant.
9558        return getContentProviderImpl(caller, name, null, stable, userId);
9559    }
9560
9561    public ContentProviderHolder getContentProviderExternal(
9562            String name, int userId, IBinder token) {
9563        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9564            "Do not have permission in call getContentProviderExternal()");
9565        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9566                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9567        return getContentProviderExternalUnchecked(name, token, userId);
9568    }
9569
9570    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9571            IBinder token, int userId) {
9572        return getContentProviderImpl(null, name, token, true, userId);
9573    }
9574
9575    /**
9576     * Drop a content provider from a ProcessRecord's bookkeeping
9577     */
9578    public void removeContentProvider(IBinder connection, boolean stable) {
9579        enforceNotIsolatedCaller("removeContentProvider");
9580        long ident = Binder.clearCallingIdentity();
9581        try {
9582            synchronized (this) {
9583                ContentProviderConnection conn;
9584                try {
9585                    conn = (ContentProviderConnection)connection;
9586                } catch (ClassCastException e) {
9587                    String msg ="removeContentProvider: " + connection
9588                            + " not a ContentProviderConnection";
9589                    Slog.w(TAG, msg);
9590                    throw new IllegalArgumentException(msg);
9591                }
9592                if (conn == null) {
9593                    throw new NullPointerException("connection is null");
9594                }
9595                if (decProviderCountLocked(conn, null, null, stable)) {
9596                    updateOomAdjLocked();
9597                }
9598            }
9599        } finally {
9600            Binder.restoreCallingIdentity(ident);
9601        }
9602    }
9603
9604    public void removeContentProviderExternal(String name, IBinder token) {
9605        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9606            "Do not have permission in call removeContentProviderExternal()");
9607        int userId = UserHandle.getCallingUserId();
9608        long ident = Binder.clearCallingIdentity();
9609        try {
9610            removeContentProviderExternalUnchecked(name, token, userId);
9611        } finally {
9612            Binder.restoreCallingIdentity(ident);
9613        }
9614    }
9615
9616    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9617        synchronized (this) {
9618            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9619            if(cpr == null) {
9620                //remove from mProvidersByClass
9621                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9622                return;
9623            }
9624
9625            //update content provider record entry info
9626            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9627            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9628            if (localCpr.hasExternalProcessHandles()) {
9629                if (localCpr.removeExternalProcessHandleLocked(token)) {
9630                    updateOomAdjLocked();
9631                } else {
9632                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9633                            + " with no external reference for token: "
9634                            + token + ".");
9635                }
9636            } else {
9637                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9638                        + " with no external references.");
9639            }
9640        }
9641    }
9642
9643    public final void publishContentProviders(IApplicationThread caller,
9644            List<ContentProviderHolder> providers) {
9645        if (providers == null) {
9646            return;
9647        }
9648
9649        enforceNotIsolatedCaller("publishContentProviders");
9650        synchronized (this) {
9651            final ProcessRecord r = getRecordForAppLocked(caller);
9652            if (DEBUG_MU)
9653                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9654            if (r == null) {
9655                throw new SecurityException(
9656                        "Unable to find app for caller " + caller
9657                      + " (pid=" + Binder.getCallingPid()
9658                      + ") when publishing content providers");
9659            }
9660
9661            final long origId = Binder.clearCallingIdentity();
9662
9663            final int N = providers.size();
9664            for (int i=0; i<N; i++) {
9665                ContentProviderHolder src = providers.get(i);
9666                if (src == null || src.info == null || src.provider == null) {
9667                    continue;
9668                }
9669                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9670                if (DEBUG_MU)
9671                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9672                if (dst != null) {
9673                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9674                    mProviderMap.putProviderByClass(comp, dst);
9675                    String names[] = dst.info.authority.split(";");
9676                    for (int j = 0; j < names.length; j++) {
9677                        mProviderMap.putProviderByName(names[j], dst);
9678                    }
9679
9680                    int NL = mLaunchingProviders.size();
9681                    int j;
9682                    for (j=0; j<NL; j++) {
9683                        if (mLaunchingProviders.get(j) == dst) {
9684                            mLaunchingProviders.remove(j);
9685                            j--;
9686                            NL--;
9687                        }
9688                    }
9689                    synchronized (dst) {
9690                        dst.provider = src.provider;
9691                        dst.proc = r;
9692                        dst.notifyAll();
9693                    }
9694                    updateOomAdjLocked(r);
9695                }
9696            }
9697
9698            Binder.restoreCallingIdentity(origId);
9699        }
9700    }
9701
9702    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9703        ContentProviderConnection conn;
9704        try {
9705            conn = (ContentProviderConnection)connection;
9706        } catch (ClassCastException e) {
9707            String msg ="refContentProvider: " + connection
9708                    + " not a ContentProviderConnection";
9709            Slog.w(TAG, msg);
9710            throw new IllegalArgumentException(msg);
9711        }
9712        if (conn == null) {
9713            throw new NullPointerException("connection is null");
9714        }
9715
9716        synchronized (this) {
9717            if (stable > 0) {
9718                conn.numStableIncs += stable;
9719            }
9720            stable = conn.stableCount + stable;
9721            if (stable < 0) {
9722                throw new IllegalStateException("stableCount < 0: " + stable);
9723            }
9724
9725            if (unstable > 0) {
9726                conn.numUnstableIncs += unstable;
9727            }
9728            unstable = conn.unstableCount + unstable;
9729            if (unstable < 0) {
9730                throw new IllegalStateException("unstableCount < 0: " + unstable);
9731            }
9732
9733            if ((stable+unstable) <= 0) {
9734                throw new IllegalStateException("ref counts can't go to zero here: stable="
9735                        + stable + " unstable=" + unstable);
9736            }
9737            conn.stableCount = stable;
9738            conn.unstableCount = unstable;
9739            return !conn.dead;
9740        }
9741    }
9742
9743    public void unstableProviderDied(IBinder connection) {
9744        ContentProviderConnection conn;
9745        try {
9746            conn = (ContentProviderConnection)connection;
9747        } catch (ClassCastException e) {
9748            String msg ="refContentProvider: " + connection
9749                    + " not a ContentProviderConnection";
9750            Slog.w(TAG, msg);
9751            throw new IllegalArgumentException(msg);
9752        }
9753        if (conn == null) {
9754            throw new NullPointerException("connection is null");
9755        }
9756
9757        // Safely retrieve the content provider associated with the connection.
9758        IContentProvider provider;
9759        synchronized (this) {
9760            provider = conn.provider.provider;
9761        }
9762
9763        if (provider == null) {
9764            // Um, yeah, we're way ahead of you.
9765            return;
9766        }
9767
9768        // Make sure the caller is being honest with us.
9769        if (provider.asBinder().pingBinder()) {
9770            // Er, no, still looks good to us.
9771            synchronized (this) {
9772                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9773                        + " says " + conn + " died, but we don't agree");
9774                return;
9775            }
9776        }
9777
9778        // Well look at that!  It's dead!
9779        synchronized (this) {
9780            if (conn.provider.provider != provider) {
9781                // But something changed...  good enough.
9782                return;
9783            }
9784
9785            ProcessRecord proc = conn.provider.proc;
9786            if (proc == null || proc.thread == null) {
9787                // Seems like the process is already cleaned up.
9788                return;
9789            }
9790
9791            // As far as we're concerned, this is just like receiving a
9792            // death notification...  just a bit prematurely.
9793            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9794                    + ") early provider death");
9795            final long ident = Binder.clearCallingIdentity();
9796            try {
9797                appDiedLocked(proc);
9798            } finally {
9799                Binder.restoreCallingIdentity(ident);
9800            }
9801        }
9802    }
9803
9804    @Override
9805    public void appNotRespondingViaProvider(IBinder connection) {
9806        enforceCallingPermission(
9807                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9808
9809        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9810        if (conn == null) {
9811            Slog.w(TAG, "ContentProviderConnection is null");
9812            return;
9813        }
9814
9815        final ProcessRecord host = conn.provider.proc;
9816        if (host == null) {
9817            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9818            return;
9819        }
9820
9821        final long token = Binder.clearCallingIdentity();
9822        try {
9823            appNotResponding(host, null, null, false, "ContentProvider not responding");
9824        } finally {
9825            Binder.restoreCallingIdentity(token);
9826        }
9827    }
9828
9829    public final void installSystemProviders() {
9830        List<ProviderInfo> providers;
9831        synchronized (this) {
9832            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9833            providers = generateApplicationProvidersLocked(app);
9834            if (providers != null) {
9835                for (int i=providers.size()-1; i>=0; i--) {
9836                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9837                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9838                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9839                                + ": not system .apk");
9840                        providers.remove(i);
9841                    }
9842                }
9843            }
9844        }
9845        if (providers != null) {
9846            mSystemThread.installSystemProviders(providers);
9847        }
9848
9849        mCoreSettingsObserver = new CoreSettingsObserver(this);
9850
9851        //mUsageStatsService.monitorPackages();
9852    }
9853
9854    /**
9855     * Allows apps to retrieve the MIME type of a URI.
9856     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9857     * users, then it does not need permission to access the ContentProvider.
9858     * Either, it needs cross-user uri grants.
9859     *
9860     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9861     *
9862     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9863     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9864     */
9865    public String getProviderMimeType(Uri uri, int userId) {
9866        enforceNotIsolatedCaller("getProviderMimeType");
9867        final String name = uri.getAuthority();
9868        int callingUid = Binder.getCallingUid();
9869        int callingPid = Binder.getCallingPid();
9870        long ident = 0;
9871        boolean clearedIdentity = false;
9872        userId = unsafeConvertIncomingUser(userId);
9873        if (canClearIdentity(callingPid, callingUid, userId)) {
9874            clearedIdentity = true;
9875            ident = Binder.clearCallingIdentity();
9876        }
9877        ContentProviderHolder holder = null;
9878        try {
9879            holder = getContentProviderExternalUnchecked(name, null, userId);
9880            if (holder != null) {
9881                return holder.provider.getType(uri);
9882            }
9883        } catch (RemoteException e) {
9884            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9885            return null;
9886        } finally {
9887            // We need to clear the identity to call removeContentProviderExternalUnchecked
9888            if (!clearedIdentity) {
9889                ident = Binder.clearCallingIdentity();
9890            }
9891            try {
9892                if (holder != null) {
9893                    removeContentProviderExternalUnchecked(name, null, userId);
9894                }
9895            } finally {
9896                Binder.restoreCallingIdentity(ident);
9897            }
9898        }
9899
9900        return null;
9901    }
9902
9903    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9904        if (UserHandle.getUserId(callingUid) == userId) {
9905            return true;
9906        }
9907        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9908                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9909                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9910                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9911                return true;
9912        }
9913        return false;
9914    }
9915
9916    // =========================================================
9917    // GLOBAL MANAGEMENT
9918    // =========================================================
9919
9920    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9921            boolean isolated, int isolatedUid) {
9922        String proc = customProcess != null ? customProcess : info.processName;
9923        BatteryStatsImpl.Uid.Proc ps = null;
9924        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9925        int uid = info.uid;
9926        if (isolated) {
9927            if (isolatedUid == 0) {
9928                int userId = UserHandle.getUserId(uid);
9929                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9930                while (true) {
9931                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9932                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9933                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9934                    }
9935                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9936                    mNextIsolatedProcessUid++;
9937                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9938                        // No process for this uid, use it.
9939                        break;
9940                    }
9941                    stepsLeft--;
9942                    if (stepsLeft <= 0) {
9943                        return null;
9944                    }
9945                }
9946            } else {
9947                // Special case for startIsolatedProcess (internal only), where
9948                // the uid of the isolated process is specified by the caller.
9949                uid = isolatedUid;
9950            }
9951        }
9952        return new ProcessRecord(stats, info, proc, uid);
9953    }
9954
9955    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9956            String abiOverride) {
9957        ProcessRecord app;
9958        if (!isolated) {
9959            app = getProcessRecordLocked(info.processName, info.uid, true);
9960        } else {
9961            app = null;
9962        }
9963
9964        if (app == null) {
9965            app = newProcessRecordLocked(info, null, isolated, 0);
9966            mProcessNames.put(info.processName, app.uid, app);
9967            if (isolated) {
9968                mIsolatedProcesses.put(app.uid, app);
9969            }
9970            updateLruProcessLocked(app, false, null);
9971            updateOomAdjLocked();
9972        }
9973
9974        // This package really, really can not be stopped.
9975        try {
9976            AppGlobals.getPackageManager().setPackageStoppedState(
9977                    info.packageName, false, UserHandle.getUserId(app.uid));
9978        } catch (RemoteException e) {
9979        } catch (IllegalArgumentException e) {
9980            Slog.w(TAG, "Failed trying to unstop package "
9981                    + info.packageName + ": " + e);
9982        }
9983
9984        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9985                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9986            app.persistent = true;
9987            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9988        }
9989        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9990            mPersistentStartingProcesses.add(app);
9991            startProcessLocked(app, "added application", app.processName, abiOverride,
9992                    null /* entryPoint */, null /* entryPointArgs */);
9993        }
9994
9995        return app;
9996    }
9997
9998    public void unhandledBack() {
9999        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10000                "unhandledBack()");
10001
10002        synchronized(this) {
10003            final long origId = Binder.clearCallingIdentity();
10004            try {
10005                getFocusedStack().unhandledBackLocked();
10006            } finally {
10007                Binder.restoreCallingIdentity(origId);
10008            }
10009        }
10010    }
10011
10012    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10013        enforceNotIsolatedCaller("openContentUri");
10014        final int userId = UserHandle.getCallingUserId();
10015        String name = uri.getAuthority();
10016        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10017        ParcelFileDescriptor pfd = null;
10018        if (cph != null) {
10019            // We record the binder invoker's uid in thread-local storage before
10020            // going to the content provider to open the file.  Later, in the code
10021            // that handles all permissions checks, we look for this uid and use
10022            // that rather than the Activity Manager's own uid.  The effect is that
10023            // we do the check against the caller's permissions even though it looks
10024            // to the content provider like the Activity Manager itself is making
10025            // the request.
10026            sCallerIdentity.set(new Identity(
10027                    Binder.getCallingPid(), Binder.getCallingUid()));
10028            try {
10029                pfd = cph.provider.openFile(null, uri, "r", null);
10030            } catch (FileNotFoundException e) {
10031                // do nothing; pfd will be returned null
10032            } finally {
10033                // Ensure that whatever happens, we clean up the identity state
10034                sCallerIdentity.remove();
10035            }
10036
10037            // We've got the fd now, so we're done with the provider.
10038            removeContentProviderExternalUnchecked(name, null, userId);
10039        } else {
10040            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10041        }
10042        return pfd;
10043    }
10044
10045    // Actually is sleeping or shutting down or whatever else in the future
10046    // is an inactive state.
10047    public boolean isSleepingOrShuttingDown() {
10048        return isSleeping() || mShuttingDown;
10049    }
10050
10051    public boolean isSleeping() {
10052        return mSleeping;
10053    }
10054
10055    void goingToSleep() {
10056        synchronized(this) {
10057            mWentToSleep = true;
10058            goToSleepIfNeededLocked();
10059        }
10060    }
10061
10062    void finishRunningVoiceLocked() {
10063        if (mRunningVoice) {
10064            mRunningVoice = false;
10065            goToSleepIfNeededLocked();
10066        }
10067    }
10068
10069    void goToSleepIfNeededLocked() {
10070        if (mWentToSleep && !mRunningVoice) {
10071            if (!mSleeping) {
10072                mSleeping = true;
10073                mStackSupervisor.goingToSleepLocked();
10074
10075                // Initialize the wake times of all processes.
10076                checkExcessivePowerUsageLocked(false);
10077                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10078                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10079                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10080            }
10081        }
10082    }
10083
10084    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10085        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10086            // Never persist the home stack.
10087            return;
10088        }
10089        mTaskPersister.wakeup(task, flush);
10090    }
10091
10092    @Override
10093    public boolean shutdown(int timeout) {
10094        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10095                != PackageManager.PERMISSION_GRANTED) {
10096            throw new SecurityException("Requires permission "
10097                    + android.Manifest.permission.SHUTDOWN);
10098        }
10099
10100        boolean timedout = false;
10101
10102        synchronized(this) {
10103            mShuttingDown = true;
10104            updateEventDispatchingLocked();
10105            timedout = mStackSupervisor.shutdownLocked(timeout);
10106        }
10107
10108        mAppOpsService.shutdown();
10109        if (mUsageStatsService != null) {
10110            mUsageStatsService.prepareShutdown();
10111        }
10112        mBatteryStatsService.shutdown();
10113        synchronized (this) {
10114            mProcessStats.shutdownLocked();
10115        }
10116        notifyTaskPersisterLocked(null, true);
10117
10118        return timedout;
10119    }
10120
10121    public final void activitySlept(IBinder token) {
10122        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10123
10124        final long origId = Binder.clearCallingIdentity();
10125
10126        synchronized (this) {
10127            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10128            if (r != null) {
10129                mStackSupervisor.activitySleptLocked(r);
10130            }
10131        }
10132
10133        Binder.restoreCallingIdentity(origId);
10134    }
10135
10136    void logLockScreen(String msg) {
10137        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10138                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10139                mWentToSleep + " mSleeping=" + mSleeping);
10140    }
10141
10142    private void comeOutOfSleepIfNeededLocked() {
10143        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10144            if (mSleeping) {
10145                mSleeping = false;
10146                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10147            }
10148        }
10149    }
10150
10151    void wakingUp() {
10152        synchronized(this) {
10153            mWentToSleep = false;
10154            comeOutOfSleepIfNeededLocked();
10155        }
10156    }
10157
10158    void startRunningVoiceLocked() {
10159        if (!mRunningVoice) {
10160            mRunningVoice = true;
10161            comeOutOfSleepIfNeededLocked();
10162        }
10163    }
10164
10165    private void updateEventDispatchingLocked() {
10166        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10167    }
10168
10169    public void setLockScreenShown(boolean shown) {
10170        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10171                != PackageManager.PERMISSION_GRANTED) {
10172            throw new SecurityException("Requires permission "
10173                    + android.Manifest.permission.DEVICE_POWER);
10174        }
10175
10176        synchronized(this) {
10177            long ident = Binder.clearCallingIdentity();
10178            try {
10179                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10180                mLockScreenShown = shown;
10181                comeOutOfSleepIfNeededLocked();
10182            } finally {
10183                Binder.restoreCallingIdentity(ident);
10184            }
10185        }
10186    }
10187
10188    @Override
10189    public void stopAppSwitches() {
10190        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10191                != PackageManager.PERMISSION_GRANTED) {
10192            throw new SecurityException("Requires permission "
10193                    + android.Manifest.permission.STOP_APP_SWITCHES);
10194        }
10195
10196        synchronized(this) {
10197            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10198                    + APP_SWITCH_DELAY_TIME;
10199            mDidAppSwitch = false;
10200            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10201            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10202            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10203        }
10204    }
10205
10206    public void resumeAppSwitches() {
10207        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10208                != PackageManager.PERMISSION_GRANTED) {
10209            throw new SecurityException("Requires permission "
10210                    + android.Manifest.permission.STOP_APP_SWITCHES);
10211        }
10212
10213        synchronized(this) {
10214            // Note that we don't execute any pending app switches... we will
10215            // let those wait until either the timeout, or the next start
10216            // activity request.
10217            mAppSwitchesAllowedTime = 0;
10218        }
10219    }
10220
10221    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10222            int callingPid, int callingUid, String name) {
10223        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10224            return true;
10225        }
10226
10227        int perm = checkComponentPermission(
10228                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10229                sourceUid, -1, true);
10230        if (perm == PackageManager.PERMISSION_GRANTED) {
10231            return true;
10232        }
10233
10234        // If the actual IPC caller is different from the logical source, then
10235        // also see if they are allowed to control app switches.
10236        if (callingUid != -1 && callingUid != sourceUid) {
10237            perm = checkComponentPermission(
10238                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10239                    callingUid, -1, true);
10240            if (perm == PackageManager.PERMISSION_GRANTED) {
10241                return true;
10242            }
10243        }
10244
10245        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10246        return false;
10247    }
10248
10249    public void setDebugApp(String packageName, boolean waitForDebugger,
10250            boolean persistent) {
10251        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10252                "setDebugApp()");
10253
10254        long ident = Binder.clearCallingIdentity();
10255        try {
10256            // Note that this is not really thread safe if there are multiple
10257            // callers into it at the same time, but that's not a situation we
10258            // care about.
10259            if (persistent) {
10260                final ContentResolver resolver = mContext.getContentResolver();
10261                Settings.Global.putString(
10262                    resolver, Settings.Global.DEBUG_APP,
10263                    packageName);
10264                Settings.Global.putInt(
10265                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10266                    waitForDebugger ? 1 : 0);
10267            }
10268
10269            synchronized (this) {
10270                if (!persistent) {
10271                    mOrigDebugApp = mDebugApp;
10272                    mOrigWaitForDebugger = mWaitForDebugger;
10273                }
10274                mDebugApp = packageName;
10275                mWaitForDebugger = waitForDebugger;
10276                mDebugTransient = !persistent;
10277                if (packageName != null) {
10278                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10279                            false, UserHandle.USER_ALL, "set debug app");
10280                }
10281            }
10282        } finally {
10283            Binder.restoreCallingIdentity(ident);
10284        }
10285    }
10286
10287    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10288        synchronized (this) {
10289            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10290            if (!isDebuggable) {
10291                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10292                    throw new SecurityException("Process not debuggable: " + app.packageName);
10293                }
10294            }
10295
10296            mOpenGlTraceApp = processName;
10297        }
10298    }
10299
10300    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10301        synchronized (this) {
10302            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10303            if (!isDebuggable) {
10304                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10305                    throw new SecurityException("Process not debuggable: " + app.packageName);
10306                }
10307            }
10308            mProfileApp = processName;
10309            mProfileFile = profilerInfo.profileFile;
10310            if (mProfileFd != null) {
10311                try {
10312                    mProfileFd.close();
10313                } catch (IOException e) {
10314                }
10315                mProfileFd = null;
10316            }
10317            mProfileFd = profilerInfo.profileFd;
10318            mSamplingInterval = profilerInfo.samplingInterval;
10319            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10320            mProfileType = 0;
10321        }
10322    }
10323
10324    @Override
10325    public void setAlwaysFinish(boolean enabled) {
10326        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10327                "setAlwaysFinish()");
10328
10329        Settings.Global.putInt(
10330                mContext.getContentResolver(),
10331                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10332
10333        synchronized (this) {
10334            mAlwaysFinishActivities = enabled;
10335        }
10336    }
10337
10338    @Override
10339    public void setActivityController(IActivityController controller) {
10340        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10341                "setActivityController()");
10342        synchronized (this) {
10343            mController = controller;
10344            Watchdog.getInstance().setActivityController(controller);
10345        }
10346    }
10347
10348    @Override
10349    public void setUserIsMonkey(boolean userIsMonkey) {
10350        synchronized (this) {
10351            synchronized (mPidsSelfLocked) {
10352                final int callingPid = Binder.getCallingPid();
10353                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10354                if (precessRecord == null) {
10355                    throw new SecurityException("Unknown process: " + callingPid);
10356                }
10357                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10358                    throw new SecurityException("Only an instrumentation process "
10359                            + "with a UiAutomation can call setUserIsMonkey");
10360                }
10361            }
10362            mUserIsMonkey = userIsMonkey;
10363        }
10364    }
10365
10366    @Override
10367    public boolean isUserAMonkey() {
10368        synchronized (this) {
10369            // If there is a controller also implies the user is a monkey.
10370            return (mUserIsMonkey || mController != null);
10371        }
10372    }
10373
10374    public void requestBugReport() {
10375        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10376        SystemProperties.set("ctl.start", "bugreport");
10377    }
10378
10379    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10380        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10381    }
10382
10383    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10384        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10385            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10386        }
10387        return KEY_DISPATCHING_TIMEOUT;
10388    }
10389
10390    @Override
10391    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10392        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10393                != PackageManager.PERMISSION_GRANTED) {
10394            throw new SecurityException("Requires permission "
10395                    + android.Manifest.permission.FILTER_EVENTS);
10396        }
10397        ProcessRecord proc;
10398        long timeout;
10399        synchronized (this) {
10400            synchronized (mPidsSelfLocked) {
10401                proc = mPidsSelfLocked.get(pid);
10402            }
10403            timeout = getInputDispatchingTimeoutLocked(proc);
10404        }
10405
10406        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10407            return -1;
10408        }
10409
10410        return timeout;
10411    }
10412
10413    /**
10414     * Handle input dispatching timeouts.
10415     * Returns whether input dispatching should be aborted or not.
10416     */
10417    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10418            final ActivityRecord activity, final ActivityRecord parent,
10419            final boolean aboveSystem, String reason) {
10420        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10421                != PackageManager.PERMISSION_GRANTED) {
10422            throw new SecurityException("Requires permission "
10423                    + android.Manifest.permission.FILTER_EVENTS);
10424        }
10425
10426        final String annotation;
10427        if (reason == null) {
10428            annotation = "Input dispatching timed out";
10429        } else {
10430            annotation = "Input dispatching timed out (" + reason + ")";
10431        }
10432
10433        if (proc != null) {
10434            synchronized (this) {
10435                if (proc.debugging) {
10436                    return false;
10437                }
10438
10439                if (mDidDexOpt) {
10440                    // Give more time since we were dexopting.
10441                    mDidDexOpt = false;
10442                    return false;
10443                }
10444
10445                if (proc.instrumentationClass != null) {
10446                    Bundle info = new Bundle();
10447                    info.putString("shortMsg", "keyDispatchingTimedOut");
10448                    info.putString("longMsg", annotation);
10449                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10450                    return true;
10451                }
10452            }
10453            mHandler.post(new Runnable() {
10454                @Override
10455                public void run() {
10456                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10457                }
10458            });
10459        }
10460
10461        return true;
10462    }
10463
10464    public Bundle getAssistContextExtras(int requestType) {
10465        PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10466                UserHandle.getCallingUserId());
10467        if (pae == null) {
10468            return null;
10469        }
10470        synchronized (pae) {
10471            while (!pae.haveResult) {
10472                try {
10473                    pae.wait();
10474                } catch (InterruptedException e) {
10475                }
10476            }
10477            if (pae.result != null) {
10478                pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10479            }
10480        }
10481        synchronized (this) {
10482            mPendingAssistExtras.remove(pae);
10483            mHandler.removeCallbacks(pae);
10484        }
10485        return pae.extras;
10486    }
10487
10488    private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10489            int userHandle) {
10490        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10491                "getAssistContextExtras()");
10492        PendingAssistExtras pae;
10493        Bundle extras = new Bundle();
10494        synchronized (this) {
10495            ActivityRecord activity = getFocusedStack().mResumedActivity;
10496            if (activity == null) {
10497                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10498                return null;
10499            }
10500            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10501            if (activity.app == null || activity.app.thread == null) {
10502                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10503                return null;
10504            }
10505            if (activity.app.pid == Binder.getCallingPid()) {
10506                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10507                return null;
10508            }
10509            pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10510            try {
10511                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10512                        requestType);
10513                mPendingAssistExtras.add(pae);
10514                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10515            } catch (RemoteException e) {
10516                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10517                return null;
10518            }
10519            return pae;
10520        }
10521    }
10522
10523    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10524        PendingAssistExtras pae = (PendingAssistExtras)token;
10525        synchronized (pae) {
10526            pae.result = extras;
10527            pae.haveResult = true;
10528            pae.notifyAll();
10529            if (pae.intent == null) {
10530                // Caller is just waiting for the result.
10531                return;
10532            }
10533        }
10534
10535        // We are now ready to launch the assist activity.
10536        synchronized (this) {
10537            boolean exists = mPendingAssistExtras.remove(pae);
10538            mHandler.removeCallbacks(pae);
10539            if (!exists) {
10540                // Timed out.
10541                return;
10542            }
10543        }
10544        pae.intent.replaceExtras(extras);
10545        if (pae.hint != null) {
10546            pae.intent.putExtra(pae.hint, true);
10547        }
10548        pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10549                | Intent.FLAG_ACTIVITY_SINGLE_TOP
10550                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10551        closeSystemDialogs("assist");
10552        try {
10553            mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10554        } catch (ActivityNotFoundException e) {
10555            Slog.w(TAG, "No activity to handle assist action.", e);
10556        }
10557    }
10558
10559    public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10560        return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10561    }
10562
10563    public void registerProcessObserver(IProcessObserver observer) {
10564        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10565                "registerProcessObserver()");
10566        synchronized (this) {
10567            mProcessObservers.register(observer);
10568        }
10569    }
10570
10571    @Override
10572    public void unregisterProcessObserver(IProcessObserver observer) {
10573        synchronized (this) {
10574            mProcessObservers.unregister(observer);
10575        }
10576    }
10577
10578    @Override
10579    public boolean convertFromTranslucent(IBinder token) {
10580        final long origId = Binder.clearCallingIdentity();
10581        try {
10582            synchronized (this) {
10583                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10584                if (r == null) {
10585                    return false;
10586                }
10587                final boolean translucentChanged = r.changeWindowTranslucency(true);
10588                if (translucentChanged) {
10589                    r.task.stack.releaseBackgroundResources();
10590                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10591                }
10592                mWindowManager.setAppFullscreen(token, true);
10593                return translucentChanged;
10594            }
10595        } finally {
10596            Binder.restoreCallingIdentity(origId);
10597        }
10598    }
10599
10600    @Override
10601    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10602        final long origId = Binder.clearCallingIdentity();
10603        try {
10604            synchronized (this) {
10605                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10606                if (r == null) {
10607                    return false;
10608                }
10609                int index = r.task.mActivities.lastIndexOf(r);
10610                if (index > 0) {
10611                    ActivityRecord under = r.task.mActivities.get(index - 1);
10612                    under.returningOptions = options;
10613                }
10614                final boolean translucentChanged = r.changeWindowTranslucency(false);
10615                if (translucentChanged) {
10616                    r.task.stack.convertToTranslucent(r);
10617                }
10618                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10619                mWindowManager.setAppFullscreen(token, false);
10620                return translucentChanged;
10621            }
10622        } finally {
10623            Binder.restoreCallingIdentity(origId);
10624        }
10625    }
10626
10627    @Override
10628    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10629        final long origId = Binder.clearCallingIdentity();
10630        try {
10631            synchronized (this) {
10632                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10633                if (r != null) {
10634                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10635                }
10636            }
10637            return false;
10638        } finally {
10639            Binder.restoreCallingIdentity(origId);
10640        }
10641    }
10642
10643    @Override
10644    public boolean isBackgroundVisibleBehind(IBinder token) {
10645        final long origId = Binder.clearCallingIdentity();
10646        try {
10647            synchronized (this) {
10648                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10649                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10650                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10651                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10652                return visible;
10653            }
10654        } finally {
10655            Binder.restoreCallingIdentity(origId);
10656        }
10657    }
10658
10659    @Override
10660    public ActivityOptions getActivityOptions(IBinder token) {
10661        final long origId = Binder.clearCallingIdentity();
10662        try {
10663            synchronized (this) {
10664                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10665                if (r != null) {
10666                    final ActivityOptions activityOptions = r.pendingOptions;
10667                    r.pendingOptions = null;
10668                    return activityOptions;
10669                }
10670                return null;
10671            }
10672        } finally {
10673            Binder.restoreCallingIdentity(origId);
10674        }
10675    }
10676
10677    @Override
10678    public void setImmersive(IBinder token, boolean immersive) {
10679        synchronized(this) {
10680            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10681            if (r == null) {
10682                throw new IllegalArgumentException();
10683            }
10684            r.immersive = immersive;
10685
10686            // update associated state if we're frontmost
10687            if (r == mFocusedActivity) {
10688                if (DEBUG_IMMERSIVE) {
10689                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10690                }
10691                applyUpdateLockStateLocked(r);
10692            }
10693        }
10694    }
10695
10696    @Override
10697    public boolean isImmersive(IBinder token) {
10698        synchronized (this) {
10699            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10700            if (r == null) {
10701                throw new IllegalArgumentException();
10702            }
10703            return r.immersive;
10704        }
10705    }
10706
10707    public boolean isTopActivityImmersive() {
10708        enforceNotIsolatedCaller("startActivity");
10709        synchronized (this) {
10710            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10711            return (r != null) ? r.immersive : false;
10712        }
10713    }
10714
10715    @Override
10716    public boolean isTopOfTask(IBinder token) {
10717        synchronized (this) {
10718            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10719            if (r == null) {
10720                throw new IllegalArgumentException();
10721            }
10722            return r.task.getTopActivity() == r;
10723        }
10724    }
10725
10726    public final void enterSafeMode() {
10727        synchronized(this) {
10728            // It only makes sense to do this before the system is ready
10729            // and started launching other packages.
10730            if (!mSystemReady) {
10731                try {
10732                    AppGlobals.getPackageManager().enterSafeMode();
10733                } catch (RemoteException e) {
10734                }
10735            }
10736
10737            mSafeMode = true;
10738        }
10739    }
10740
10741    public final void showSafeModeOverlay() {
10742        View v = LayoutInflater.from(mContext).inflate(
10743                com.android.internal.R.layout.safe_mode, null);
10744        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10745        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10746        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10747        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10748        lp.gravity = Gravity.BOTTOM | Gravity.START;
10749        lp.format = v.getBackground().getOpacity();
10750        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10751                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10752        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10753        ((WindowManager)mContext.getSystemService(
10754                Context.WINDOW_SERVICE)).addView(v, lp);
10755    }
10756
10757    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10758        if (!(sender instanceof PendingIntentRecord)) {
10759            return;
10760        }
10761        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10762        synchronized (stats) {
10763            if (mBatteryStatsService.isOnBattery()) {
10764                mBatteryStatsService.enforceCallingPermission();
10765                PendingIntentRecord rec = (PendingIntentRecord)sender;
10766                int MY_UID = Binder.getCallingUid();
10767                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10768                BatteryStatsImpl.Uid.Pkg pkg =
10769                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10770                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10771                pkg.incWakeupsLocked();
10772            }
10773        }
10774    }
10775
10776    public boolean killPids(int[] pids, String pReason, boolean secure) {
10777        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10778            throw new SecurityException("killPids only available to the system");
10779        }
10780        String reason = (pReason == null) ? "Unknown" : pReason;
10781        // XXX Note: don't acquire main activity lock here, because the window
10782        // manager calls in with its locks held.
10783
10784        boolean killed = false;
10785        synchronized (mPidsSelfLocked) {
10786            int[] types = new int[pids.length];
10787            int worstType = 0;
10788            for (int i=0; i<pids.length; i++) {
10789                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10790                if (proc != null) {
10791                    int type = proc.setAdj;
10792                    types[i] = type;
10793                    if (type > worstType) {
10794                        worstType = type;
10795                    }
10796                }
10797            }
10798
10799            // If the worst oom_adj is somewhere in the cached proc LRU range,
10800            // then constrain it so we will kill all cached procs.
10801            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10802                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10803                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10804            }
10805
10806            // If this is not a secure call, don't let it kill processes that
10807            // are important.
10808            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10809                worstType = ProcessList.SERVICE_ADJ;
10810            }
10811
10812            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10813            for (int i=0; i<pids.length; i++) {
10814                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10815                if (proc == null) {
10816                    continue;
10817                }
10818                int adj = proc.setAdj;
10819                if (adj >= worstType && !proc.killedByAm) {
10820                    proc.kill(reason, true);
10821                    killed = true;
10822                }
10823            }
10824        }
10825        return killed;
10826    }
10827
10828    @Override
10829    public void killUid(int uid, String reason) {
10830        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10831            throw new SecurityException("killUid only available to the system");
10832        }
10833        synchronized (this) {
10834            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10835                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10836                    reason != null ? reason : "kill uid");
10837        }
10838    }
10839
10840    @Override
10841    public boolean killProcessesBelowForeground(String reason) {
10842        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10843            throw new SecurityException("killProcessesBelowForeground() only available to system");
10844        }
10845
10846        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10847    }
10848
10849    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10850        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10851            throw new SecurityException("killProcessesBelowAdj() only available to system");
10852        }
10853
10854        boolean killed = false;
10855        synchronized (mPidsSelfLocked) {
10856            final int size = mPidsSelfLocked.size();
10857            for (int i = 0; i < size; i++) {
10858                final int pid = mPidsSelfLocked.keyAt(i);
10859                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10860                if (proc == null) continue;
10861
10862                final int adj = proc.setAdj;
10863                if (adj > belowAdj && !proc.killedByAm) {
10864                    proc.kill(reason, true);
10865                    killed = true;
10866                }
10867            }
10868        }
10869        return killed;
10870    }
10871
10872    @Override
10873    public void hang(final IBinder who, boolean allowRestart) {
10874        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10875                != PackageManager.PERMISSION_GRANTED) {
10876            throw new SecurityException("Requires permission "
10877                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10878        }
10879
10880        final IBinder.DeathRecipient death = new DeathRecipient() {
10881            @Override
10882            public void binderDied() {
10883                synchronized (this) {
10884                    notifyAll();
10885                }
10886            }
10887        };
10888
10889        try {
10890            who.linkToDeath(death, 0);
10891        } catch (RemoteException e) {
10892            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10893            return;
10894        }
10895
10896        synchronized (this) {
10897            Watchdog.getInstance().setAllowRestart(allowRestart);
10898            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10899            synchronized (death) {
10900                while (who.isBinderAlive()) {
10901                    try {
10902                        death.wait();
10903                    } catch (InterruptedException e) {
10904                    }
10905                }
10906            }
10907            Watchdog.getInstance().setAllowRestart(true);
10908        }
10909    }
10910
10911    @Override
10912    public void restart() {
10913        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10914                != PackageManager.PERMISSION_GRANTED) {
10915            throw new SecurityException("Requires permission "
10916                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10917        }
10918
10919        Log.i(TAG, "Sending shutdown broadcast...");
10920
10921        BroadcastReceiver br = new BroadcastReceiver() {
10922            @Override public void onReceive(Context context, Intent intent) {
10923                // Now the broadcast is done, finish up the low-level shutdown.
10924                Log.i(TAG, "Shutting down activity manager...");
10925                shutdown(10000);
10926                Log.i(TAG, "Shutdown complete, restarting!");
10927                Process.killProcess(Process.myPid());
10928                System.exit(10);
10929            }
10930        };
10931
10932        // First send the high-level shut down broadcast.
10933        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10934        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10935        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10936        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10937        mContext.sendOrderedBroadcastAsUser(intent,
10938                UserHandle.ALL, null, br, mHandler, 0, null, null);
10939        */
10940        br.onReceive(mContext, intent);
10941    }
10942
10943    private long getLowRamTimeSinceIdle(long now) {
10944        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10945    }
10946
10947    @Override
10948    public void performIdleMaintenance() {
10949        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10950                != PackageManager.PERMISSION_GRANTED) {
10951            throw new SecurityException("Requires permission "
10952                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10953        }
10954
10955        synchronized (this) {
10956            final long now = SystemClock.uptimeMillis();
10957            final long timeSinceLastIdle = now - mLastIdleTime;
10958            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10959            mLastIdleTime = now;
10960            mLowRamTimeSinceLastIdle = 0;
10961            if (mLowRamStartTime != 0) {
10962                mLowRamStartTime = now;
10963            }
10964
10965            StringBuilder sb = new StringBuilder(128);
10966            sb.append("Idle maintenance over ");
10967            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10968            sb.append(" low RAM for ");
10969            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10970            Slog.i(TAG, sb.toString());
10971
10972            // If at least 1/3 of our time since the last idle period has been spent
10973            // with RAM low, then we want to kill processes.
10974            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10975
10976            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10977                ProcessRecord proc = mLruProcesses.get(i);
10978                if (proc.notCachedSinceIdle) {
10979                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10980                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10981                        if (doKilling && proc.initialIdlePss != 0
10982                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10983                            proc.kill("idle maint (pss " + proc.lastPss
10984                                    + " from " + proc.initialIdlePss + ")", true);
10985                        }
10986                    }
10987                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10988                    proc.notCachedSinceIdle = true;
10989                    proc.initialIdlePss = 0;
10990                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10991                            isSleeping(), now);
10992                }
10993            }
10994
10995            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10996            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10997        }
10998    }
10999
11000    private void retrieveSettings() {
11001        final ContentResolver resolver = mContext.getContentResolver();
11002        String debugApp = Settings.Global.getString(
11003            resolver, Settings.Global.DEBUG_APP);
11004        boolean waitForDebugger = Settings.Global.getInt(
11005            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11006        boolean alwaysFinishActivities = Settings.Global.getInt(
11007            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11008        boolean forceRtl = Settings.Global.getInt(
11009                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11010        // Transfer any global setting for forcing RTL layout, into a System Property
11011        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11012
11013        Configuration configuration = new Configuration();
11014        Settings.System.getConfiguration(resolver, configuration);
11015        if (forceRtl) {
11016            // This will take care of setting the correct layout direction flags
11017            configuration.setLayoutDirection(configuration.locale);
11018        }
11019
11020        synchronized (this) {
11021            mDebugApp = mOrigDebugApp = debugApp;
11022            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11023            mAlwaysFinishActivities = alwaysFinishActivities;
11024            // This happens before any activities are started, so we can
11025            // change mConfiguration in-place.
11026            updateConfigurationLocked(configuration, null, false, true);
11027            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11028        }
11029    }
11030
11031    /** Loads resources after the current configuration has been set. */
11032    private void loadResourcesOnSystemReady() {
11033        final Resources res = mContext.getResources();
11034        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11035        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11036        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11037    }
11038
11039    public boolean testIsSystemReady() {
11040        // no need to synchronize(this) just to read & return the value
11041        return mSystemReady;
11042    }
11043
11044    private static File getCalledPreBootReceiversFile() {
11045        File dataDir = Environment.getDataDirectory();
11046        File systemDir = new File(dataDir, "system");
11047        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11048        return fname;
11049    }
11050
11051    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11052        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11053        File file = getCalledPreBootReceiversFile();
11054        FileInputStream fis = null;
11055        try {
11056            fis = new FileInputStream(file);
11057            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11058            int fvers = dis.readInt();
11059            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11060                String vers = dis.readUTF();
11061                String codename = dis.readUTF();
11062                String build = dis.readUTF();
11063                if (android.os.Build.VERSION.RELEASE.equals(vers)
11064                        && android.os.Build.VERSION.CODENAME.equals(codename)
11065                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11066                    int num = dis.readInt();
11067                    while (num > 0) {
11068                        num--;
11069                        String pkg = dis.readUTF();
11070                        String cls = dis.readUTF();
11071                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11072                    }
11073                }
11074            }
11075        } catch (FileNotFoundException e) {
11076        } catch (IOException e) {
11077            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11078        } finally {
11079            if (fis != null) {
11080                try {
11081                    fis.close();
11082                } catch (IOException e) {
11083                }
11084            }
11085        }
11086        return lastDoneReceivers;
11087    }
11088
11089    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11090        File file = getCalledPreBootReceiversFile();
11091        FileOutputStream fos = null;
11092        DataOutputStream dos = null;
11093        try {
11094            fos = new FileOutputStream(file);
11095            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11096            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11097            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11098            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11099            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11100            dos.writeInt(list.size());
11101            for (int i=0; i<list.size(); i++) {
11102                dos.writeUTF(list.get(i).getPackageName());
11103                dos.writeUTF(list.get(i).getClassName());
11104            }
11105        } catch (IOException e) {
11106            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11107            file.delete();
11108        } finally {
11109            FileUtils.sync(fos);
11110            if (dos != null) {
11111                try {
11112                    dos.close();
11113                } catch (IOException e) {
11114                    // TODO Auto-generated catch block
11115                    e.printStackTrace();
11116                }
11117            }
11118        }
11119    }
11120
11121    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11122            ArrayList<ComponentName> doneReceivers, int userId) {
11123        boolean waitingUpdate = false;
11124        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11125        List<ResolveInfo> ris = null;
11126        try {
11127            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11128                    intent, null, 0, userId);
11129        } catch (RemoteException e) {
11130        }
11131        if (ris != null) {
11132            for (int i=ris.size()-1; i>=0; i--) {
11133                if ((ris.get(i).activityInfo.applicationInfo.flags
11134                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11135                    ris.remove(i);
11136                }
11137            }
11138            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11139
11140            // For User 0, load the version number. When delivering to a new user, deliver
11141            // to all receivers.
11142            if (userId == UserHandle.USER_OWNER) {
11143                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11144                for (int i=0; i<ris.size(); i++) {
11145                    ActivityInfo ai = ris.get(i).activityInfo;
11146                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11147                    if (lastDoneReceivers.contains(comp)) {
11148                        // We already did the pre boot receiver for this app with the current
11149                        // platform version, so don't do it again...
11150                        ris.remove(i);
11151                        i--;
11152                        // ...however, do keep it as one that has been done, so we don't
11153                        // forget about it when rewriting the file of last done receivers.
11154                        doneReceivers.add(comp);
11155                    }
11156                }
11157            }
11158
11159            // If primary user, send broadcast to all available users, else just to userId
11160            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11161                    : new int[] { userId };
11162            for (int i = 0; i < ris.size(); i++) {
11163                ActivityInfo ai = ris.get(i).activityInfo;
11164                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11165                doneReceivers.add(comp);
11166                intent.setComponent(comp);
11167                for (int j=0; j<users.length; j++) {
11168                    IIntentReceiver finisher = null;
11169                    // On last receiver and user, set up a completion callback
11170                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11171                        finisher = new IIntentReceiver.Stub() {
11172                            public void performReceive(Intent intent, int resultCode,
11173                                    String data, Bundle extras, boolean ordered,
11174                                    boolean sticky, int sendingUser) {
11175                                // The raw IIntentReceiver interface is called
11176                                // with the AM lock held, so redispatch to
11177                                // execute our code without the lock.
11178                                mHandler.post(onFinishCallback);
11179                            }
11180                        };
11181                    }
11182                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11183                            + " for user " + users[j]);
11184                    broadcastIntentLocked(null, null, intent, null, finisher,
11185                            0, null, null, null, AppOpsManager.OP_NONE,
11186                            true, false, MY_PID, Process.SYSTEM_UID,
11187                            users[j]);
11188                    if (finisher != null) {
11189                        waitingUpdate = true;
11190                    }
11191                }
11192            }
11193        }
11194
11195        return waitingUpdate;
11196    }
11197
11198    public void systemReady(final Runnable goingCallback) {
11199        synchronized(this) {
11200            if (mSystemReady) {
11201                // If we're done calling all the receivers, run the next "boot phase" passed in
11202                // by the SystemServer
11203                if (goingCallback != null) {
11204                    goingCallback.run();
11205                }
11206                return;
11207            }
11208
11209            // Make sure we have the current profile info, since it is needed for
11210            // security checks.
11211            updateCurrentProfileIdsLocked();
11212
11213            if (mRecentTasks == null) {
11214                mRecentTasks = mTaskPersister.restoreTasksLocked();
11215                if (!mRecentTasks.isEmpty()) {
11216                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11217                }
11218                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11219                mTaskPersister.startPersisting();
11220            }
11221
11222            // Check to see if there are any update receivers to run.
11223            if (!mDidUpdate) {
11224                if (mWaitingUpdate) {
11225                    return;
11226                }
11227                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11228                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11229                    public void run() {
11230                        synchronized (ActivityManagerService.this) {
11231                            mDidUpdate = true;
11232                        }
11233                        writeLastDonePreBootReceivers(doneReceivers);
11234                        showBootMessage(mContext.getText(
11235                                R.string.android_upgrading_complete),
11236                                false);
11237                        systemReady(goingCallback);
11238                    }
11239                }, doneReceivers, UserHandle.USER_OWNER);
11240
11241                if (mWaitingUpdate) {
11242                    return;
11243                }
11244                mDidUpdate = true;
11245            }
11246
11247            mAppOpsService.systemReady();
11248            mSystemReady = true;
11249        }
11250
11251        ArrayList<ProcessRecord> procsToKill = null;
11252        synchronized(mPidsSelfLocked) {
11253            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11254                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11255                if (!isAllowedWhileBooting(proc.info)){
11256                    if (procsToKill == null) {
11257                        procsToKill = new ArrayList<ProcessRecord>();
11258                    }
11259                    procsToKill.add(proc);
11260                }
11261            }
11262        }
11263
11264        synchronized(this) {
11265            if (procsToKill != null) {
11266                for (int i=procsToKill.size()-1; i>=0; i--) {
11267                    ProcessRecord proc = procsToKill.get(i);
11268                    Slog.i(TAG, "Removing system update proc: " + proc);
11269                    removeProcessLocked(proc, true, false, "system update done");
11270                }
11271            }
11272
11273            // Now that we have cleaned up any update processes, we
11274            // are ready to start launching real processes and know that
11275            // we won't trample on them any more.
11276            mProcessesReady = true;
11277        }
11278
11279        Slog.i(TAG, "System now ready");
11280        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11281            SystemClock.uptimeMillis());
11282
11283        synchronized(this) {
11284            // Make sure we have no pre-ready processes sitting around.
11285
11286            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11287                ResolveInfo ri = mContext.getPackageManager()
11288                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11289                                STOCK_PM_FLAGS);
11290                CharSequence errorMsg = null;
11291                if (ri != null) {
11292                    ActivityInfo ai = ri.activityInfo;
11293                    ApplicationInfo app = ai.applicationInfo;
11294                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11295                        mTopAction = Intent.ACTION_FACTORY_TEST;
11296                        mTopData = null;
11297                        mTopComponent = new ComponentName(app.packageName,
11298                                ai.name);
11299                    } else {
11300                        errorMsg = mContext.getResources().getText(
11301                                com.android.internal.R.string.factorytest_not_system);
11302                    }
11303                } else {
11304                    errorMsg = mContext.getResources().getText(
11305                            com.android.internal.R.string.factorytest_no_action);
11306                }
11307                if (errorMsg != null) {
11308                    mTopAction = null;
11309                    mTopData = null;
11310                    mTopComponent = null;
11311                    Message msg = Message.obtain();
11312                    msg.what = SHOW_FACTORY_ERROR_MSG;
11313                    msg.getData().putCharSequence("msg", errorMsg);
11314                    mHandler.sendMessage(msg);
11315                }
11316            }
11317        }
11318
11319        retrieveSettings();
11320        loadResourcesOnSystemReady();
11321
11322        synchronized (this) {
11323            readGrantedUriPermissionsLocked();
11324        }
11325
11326        if (goingCallback != null) goingCallback.run();
11327
11328        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11329                Integer.toString(mCurrentUserId), mCurrentUserId);
11330        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11331                Integer.toString(mCurrentUserId), mCurrentUserId);
11332        mSystemServiceManager.startUser(mCurrentUserId);
11333
11334        synchronized (this) {
11335            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11336                try {
11337                    List apps = AppGlobals.getPackageManager().
11338                        getPersistentApplications(STOCK_PM_FLAGS);
11339                    if (apps != null) {
11340                        int N = apps.size();
11341                        int i;
11342                        for (i=0; i<N; i++) {
11343                            ApplicationInfo info
11344                                = (ApplicationInfo)apps.get(i);
11345                            if (info != null &&
11346                                    !info.packageName.equals("android")) {
11347                                addAppLocked(info, false, null /* ABI override */);
11348                            }
11349                        }
11350                    }
11351                } catch (RemoteException ex) {
11352                    // pm is in same process, this will never happen.
11353                }
11354            }
11355
11356            // Start up initial activity.
11357            mBooting = true;
11358            startHomeActivityLocked(mCurrentUserId);
11359
11360            try {
11361                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11362                    Message msg = Message.obtain();
11363                    msg.what = SHOW_UID_ERROR_MSG;
11364                    mHandler.sendMessage(msg);
11365                }
11366            } catch (RemoteException e) {
11367            }
11368
11369            long ident = Binder.clearCallingIdentity();
11370            try {
11371                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11372                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11373                        | Intent.FLAG_RECEIVER_FOREGROUND);
11374                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11375                broadcastIntentLocked(null, null, intent,
11376                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11377                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11378                intent = new Intent(Intent.ACTION_USER_STARTING);
11379                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11380                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11381                broadcastIntentLocked(null, null, intent,
11382                        null, new IIntentReceiver.Stub() {
11383                            @Override
11384                            public void performReceive(Intent intent, int resultCode, String data,
11385                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11386                                    throws RemoteException {
11387                            }
11388                        }, 0, null, null,
11389                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11390                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11391            } catch (Throwable t) {
11392                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11393            } finally {
11394                Binder.restoreCallingIdentity(ident);
11395            }
11396            mStackSupervisor.resumeTopActivitiesLocked();
11397            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11398        }
11399    }
11400
11401    private boolean makeAppCrashingLocked(ProcessRecord app,
11402            String shortMsg, String longMsg, String stackTrace) {
11403        app.crashing = true;
11404        app.crashingReport = generateProcessError(app,
11405                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11406        startAppProblemLocked(app);
11407        app.stopFreezingAllLocked();
11408        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11409    }
11410
11411    private void makeAppNotRespondingLocked(ProcessRecord app,
11412            String activity, String shortMsg, String longMsg) {
11413        app.notResponding = true;
11414        app.notRespondingReport = generateProcessError(app,
11415                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11416                activity, shortMsg, longMsg, null);
11417        startAppProblemLocked(app);
11418        app.stopFreezingAllLocked();
11419    }
11420
11421    /**
11422     * Generate a process error record, suitable for attachment to a ProcessRecord.
11423     *
11424     * @param app The ProcessRecord in which the error occurred.
11425     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11426     *                      ActivityManager.AppErrorStateInfo
11427     * @param activity The activity associated with the crash, if known.
11428     * @param shortMsg Short message describing the crash.
11429     * @param longMsg Long message describing the crash.
11430     * @param stackTrace Full crash stack trace, may be null.
11431     *
11432     * @return Returns a fully-formed AppErrorStateInfo record.
11433     */
11434    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11435            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11436        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11437
11438        report.condition = condition;
11439        report.processName = app.processName;
11440        report.pid = app.pid;
11441        report.uid = app.info.uid;
11442        report.tag = activity;
11443        report.shortMsg = shortMsg;
11444        report.longMsg = longMsg;
11445        report.stackTrace = stackTrace;
11446
11447        return report;
11448    }
11449
11450    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11451        synchronized (this) {
11452            app.crashing = false;
11453            app.crashingReport = null;
11454            app.notResponding = false;
11455            app.notRespondingReport = null;
11456            if (app.anrDialog == fromDialog) {
11457                app.anrDialog = null;
11458            }
11459            if (app.waitDialog == fromDialog) {
11460                app.waitDialog = null;
11461            }
11462            if (app.pid > 0 && app.pid != MY_PID) {
11463                handleAppCrashLocked(app, null, null, null);
11464                app.kill("user request after error", true);
11465            }
11466        }
11467    }
11468
11469    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11470            String stackTrace) {
11471        long now = SystemClock.uptimeMillis();
11472
11473        Long crashTime;
11474        if (!app.isolated) {
11475            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11476        } else {
11477            crashTime = null;
11478        }
11479        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11480            // This process loses!
11481            Slog.w(TAG, "Process " + app.info.processName
11482                    + " has crashed too many times: killing!");
11483            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11484                    app.userId, app.info.processName, app.uid);
11485            mStackSupervisor.handleAppCrashLocked(app);
11486            if (!app.persistent) {
11487                // We don't want to start this process again until the user
11488                // explicitly does so...  but for persistent process, we really
11489                // need to keep it running.  If a persistent process is actually
11490                // repeatedly crashing, then badness for everyone.
11491                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11492                        app.info.processName);
11493                if (!app.isolated) {
11494                    // XXX We don't have a way to mark isolated processes
11495                    // as bad, since they don't have a peristent identity.
11496                    mBadProcesses.put(app.info.processName, app.uid,
11497                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11498                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11499                }
11500                app.bad = true;
11501                app.removed = true;
11502                // Don't let services in this process be restarted and potentially
11503                // annoy the user repeatedly.  Unless it is persistent, since those
11504                // processes run critical code.
11505                removeProcessLocked(app, false, false, "crash");
11506                mStackSupervisor.resumeTopActivitiesLocked();
11507                return false;
11508            }
11509            mStackSupervisor.resumeTopActivitiesLocked();
11510        } else {
11511            mStackSupervisor.finishTopRunningActivityLocked(app);
11512        }
11513
11514        // Bump up the crash count of any services currently running in the proc.
11515        for (int i=app.services.size()-1; i>=0; i--) {
11516            // Any services running in the application need to be placed
11517            // back in the pending list.
11518            ServiceRecord sr = app.services.valueAt(i);
11519            sr.crashCount++;
11520        }
11521
11522        // If the crashing process is what we consider to be the "home process" and it has been
11523        // replaced by a third-party app, clear the package preferred activities from packages
11524        // with a home activity running in the process to prevent a repeatedly crashing app
11525        // from blocking the user to manually clear the list.
11526        final ArrayList<ActivityRecord> activities = app.activities;
11527        if (app == mHomeProcess && activities.size() > 0
11528                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11529            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11530                final ActivityRecord r = activities.get(activityNdx);
11531                if (r.isHomeActivity()) {
11532                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11533                    try {
11534                        ActivityThread.getPackageManager()
11535                                .clearPackagePreferredActivities(r.packageName);
11536                    } catch (RemoteException c) {
11537                        // pm is in same process, this will never happen.
11538                    }
11539                }
11540            }
11541        }
11542
11543        if (!app.isolated) {
11544            // XXX Can't keep track of crash times for isolated processes,
11545            // because they don't have a perisistent identity.
11546            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11547        }
11548
11549        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11550        return true;
11551    }
11552
11553    void startAppProblemLocked(ProcessRecord app) {
11554        // If this app is not running under the current user, then we
11555        // can't give it a report button because that would require
11556        // launching the report UI under a different user.
11557        app.errorReportReceiver = null;
11558
11559        for (int userId : mCurrentProfileIds) {
11560            if (app.userId == userId) {
11561                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11562                        mContext, app.info.packageName, app.info.flags);
11563            }
11564        }
11565        skipCurrentReceiverLocked(app);
11566    }
11567
11568    void skipCurrentReceiverLocked(ProcessRecord app) {
11569        for (BroadcastQueue queue : mBroadcastQueues) {
11570            queue.skipCurrentReceiverLocked(app);
11571        }
11572    }
11573
11574    /**
11575     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11576     * The application process will exit immediately after this call returns.
11577     * @param app object of the crashing app, null for the system server
11578     * @param crashInfo describing the exception
11579     */
11580    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11581        ProcessRecord r = findAppProcess(app, "Crash");
11582        final String processName = app == null ? "system_server"
11583                : (r == null ? "unknown" : r.processName);
11584
11585        handleApplicationCrashInner("crash", r, processName, crashInfo);
11586    }
11587
11588    /* Native crash reporting uses this inner version because it needs to be somewhat
11589     * decoupled from the AM-managed cleanup lifecycle
11590     */
11591    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11592            ApplicationErrorReport.CrashInfo crashInfo) {
11593        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11594                UserHandle.getUserId(Binder.getCallingUid()), processName,
11595                r == null ? -1 : r.info.flags,
11596                crashInfo.exceptionClassName,
11597                crashInfo.exceptionMessage,
11598                crashInfo.throwFileName,
11599                crashInfo.throwLineNumber);
11600
11601        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11602
11603        crashApplication(r, crashInfo);
11604    }
11605
11606    public void handleApplicationStrictModeViolation(
11607            IBinder app,
11608            int violationMask,
11609            StrictMode.ViolationInfo info) {
11610        ProcessRecord r = findAppProcess(app, "StrictMode");
11611        if (r == null) {
11612            return;
11613        }
11614
11615        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11616            Integer stackFingerprint = info.hashCode();
11617            boolean logIt = true;
11618            synchronized (mAlreadyLoggedViolatedStacks) {
11619                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11620                    logIt = false;
11621                    // TODO: sub-sample into EventLog for these, with
11622                    // the info.durationMillis?  Then we'd get
11623                    // the relative pain numbers, without logging all
11624                    // the stack traces repeatedly.  We'd want to do
11625                    // likewise in the client code, which also does
11626                    // dup suppression, before the Binder call.
11627                } else {
11628                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11629                        mAlreadyLoggedViolatedStacks.clear();
11630                    }
11631                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11632                }
11633            }
11634            if (logIt) {
11635                logStrictModeViolationToDropBox(r, info);
11636            }
11637        }
11638
11639        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11640            AppErrorResult result = new AppErrorResult();
11641            synchronized (this) {
11642                final long origId = Binder.clearCallingIdentity();
11643
11644                Message msg = Message.obtain();
11645                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11646                HashMap<String, Object> data = new HashMap<String, Object>();
11647                data.put("result", result);
11648                data.put("app", r);
11649                data.put("violationMask", violationMask);
11650                data.put("info", info);
11651                msg.obj = data;
11652                mHandler.sendMessage(msg);
11653
11654                Binder.restoreCallingIdentity(origId);
11655            }
11656            int res = result.get();
11657            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11658        }
11659    }
11660
11661    // Depending on the policy in effect, there could be a bunch of
11662    // these in quick succession so we try to batch these together to
11663    // minimize disk writes, number of dropbox entries, and maximize
11664    // compression, by having more fewer, larger records.
11665    private void logStrictModeViolationToDropBox(
11666            ProcessRecord process,
11667            StrictMode.ViolationInfo info) {
11668        if (info == null) {
11669            return;
11670        }
11671        final boolean isSystemApp = process == null ||
11672                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11673                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11674        final String processName = process == null ? "unknown" : process.processName;
11675        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11676        final DropBoxManager dbox = (DropBoxManager)
11677                mContext.getSystemService(Context.DROPBOX_SERVICE);
11678
11679        // Exit early if the dropbox isn't configured to accept this report type.
11680        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11681
11682        boolean bufferWasEmpty;
11683        boolean needsFlush;
11684        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11685        synchronized (sb) {
11686            bufferWasEmpty = sb.length() == 0;
11687            appendDropBoxProcessHeaders(process, processName, sb);
11688            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11689            sb.append("System-App: ").append(isSystemApp).append("\n");
11690            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11691            if (info.violationNumThisLoop != 0) {
11692                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11693            }
11694            if (info.numAnimationsRunning != 0) {
11695                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11696            }
11697            if (info.broadcastIntentAction != null) {
11698                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11699            }
11700            if (info.durationMillis != -1) {
11701                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11702            }
11703            if (info.numInstances != -1) {
11704                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11705            }
11706            if (info.tags != null) {
11707                for (String tag : info.tags) {
11708                    sb.append("Span-Tag: ").append(tag).append("\n");
11709                }
11710            }
11711            sb.append("\n");
11712            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11713                sb.append(info.crashInfo.stackTrace);
11714            }
11715            sb.append("\n");
11716
11717            // Only buffer up to ~64k.  Various logging bits truncate
11718            // things at 128k.
11719            needsFlush = (sb.length() > 64 * 1024);
11720        }
11721
11722        // Flush immediately if the buffer's grown too large, or this
11723        // is a non-system app.  Non-system apps are isolated with a
11724        // different tag & policy and not batched.
11725        //
11726        // Batching is useful during internal testing with
11727        // StrictMode settings turned up high.  Without batching,
11728        // thousands of separate files could be created on boot.
11729        if (!isSystemApp || needsFlush) {
11730            new Thread("Error dump: " + dropboxTag) {
11731                @Override
11732                public void run() {
11733                    String report;
11734                    synchronized (sb) {
11735                        report = sb.toString();
11736                        sb.delete(0, sb.length());
11737                        sb.trimToSize();
11738                    }
11739                    if (report.length() != 0) {
11740                        dbox.addText(dropboxTag, report);
11741                    }
11742                }
11743            }.start();
11744            return;
11745        }
11746
11747        // System app batching:
11748        if (!bufferWasEmpty) {
11749            // An existing dropbox-writing thread is outstanding, so
11750            // we don't need to start it up.  The existing thread will
11751            // catch the buffer appends we just did.
11752            return;
11753        }
11754
11755        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11756        // (After this point, we shouldn't access AMS internal data structures.)
11757        new Thread("Error dump: " + dropboxTag) {
11758            @Override
11759            public void run() {
11760                // 5 second sleep to let stacks arrive and be batched together
11761                try {
11762                    Thread.sleep(5000);  // 5 seconds
11763                } catch (InterruptedException e) {}
11764
11765                String errorReport;
11766                synchronized (mStrictModeBuffer) {
11767                    errorReport = mStrictModeBuffer.toString();
11768                    if (errorReport.length() == 0) {
11769                        return;
11770                    }
11771                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11772                    mStrictModeBuffer.trimToSize();
11773                }
11774                dbox.addText(dropboxTag, errorReport);
11775            }
11776        }.start();
11777    }
11778
11779    /**
11780     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11781     * @param app object of the crashing app, null for the system server
11782     * @param tag reported by the caller
11783     * @param system whether this wtf is coming from the system
11784     * @param crashInfo describing the context of the error
11785     * @return true if the process should exit immediately (WTF is fatal)
11786     */
11787    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11788            final ApplicationErrorReport.CrashInfo crashInfo) {
11789        final int callingUid = Binder.getCallingUid();
11790        final int callingPid = Binder.getCallingPid();
11791
11792        if (system) {
11793            // If this is coming from the system, we could very well have low-level
11794            // system locks held, so we want to do this all asynchronously.  And we
11795            // never want this to become fatal, so there is that too.
11796            mHandler.post(new Runnable() {
11797                @Override public void run() {
11798                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11799                }
11800            });
11801            return false;
11802        }
11803
11804        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11805                crashInfo);
11806
11807        if (r != null && r.pid != Process.myPid() &&
11808                Settings.Global.getInt(mContext.getContentResolver(),
11809                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11810            crashApplication(r, crashInfo);
11811            return true;
11812        } else {
11813            return false;
11814        }
11815    }
11816
11817    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11818            final ApplicationErrorReport.CrashInfo crashInfo) {
11819        final ProcessRecord r = findAppProcess(app, "WTF");
11820        final String processName = app == null ? "system_server"
11821                : (r == null ? "unknown" : r.processName);
11822
11823        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11824                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11825
11826        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11827
11828        return r;
11829    }
11830
11831    /**
11832     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11833     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11834     */
11835    private ProcessRecord findAppProcess(IBinder app, String reason) {
11836        if (app == null) {
11837            return null;
11838        }
11839
11840        synchronized (this) {
11841            final int NP = mProcessNames.getMap().size();
11842            for (int ip=0; ip<NP; ip++) {
11843                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11844                final int NA = apps.size();
11845                for (int ia=0; ia<NA; ia++) {
11846                    ProcessRecord p = apps.valueAt(ia);
11847                    if (p.thread != null && p.thread.asBinder() == app) {
11848                        return p;
11849                    }
11850                }
11851            }
11852
11853            Slog.w(TAG, "Can't find mystery application for " + reason
11854                    + " from pid=" + Binder.getCallingPid()
11855                    + " uid=" + Binder.getCallingUid() + ": " + app);
11856            return null;
11857        }
11858    }
11859
11860    /**
11861     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11862     * to append various headers to the dropbox log text.
11863     */
11864    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11865            StringBuilder sb) {
11866        // Watchdog thread ends up invoking this function (with
11867        // a null ProcessRecord) to add the stack file to dropbox.
11868        // Do not acquire a lock on this (am) in such cases, as it
11869        // could cause a potential deadlock, if and when watchdog
11870        // is invoked due to unavailability of lock on am and it
11871        // would prevent watchdog from killing system_server.
11872        if (process == null) {
11873            sb.append("Process: ").append(processName).append("\n");
11874            return;
11875        }
11876        // Note: ProcessRecord 'process' is guarded by the service
11877        // instance.  (notably process.pkgList, which could otherwise change
11878        // concurrently during execution of this method)
11879        synchronized (this) {
11880            sb.append("Process: ").append(processName).append("\n");
11881            int flags = process.info.flags;
11882            IPackageManager pm = AppGlobals.getPackageManager();
11883            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11884            for (int ip=0; ip<process.pkgList.size(); ip++) {
11885                String pkg = process.pkgList.keyAt(ip);
11886                sb.append("Package: ").append(pkg);
11887                try {
11888                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11889                    if (pi != null) {
11890                        sb.append(" v").append(pi.versionCode);
11891                        if (pi.versionName != null) {
11892                            sb.append(" (").append(pi.versionName).append(")");
11893                        }
11894                    }
11895                } catch (RemoteException e) {
11896                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11897                }
11898                sb.append("\n");
11899            }
11900        }
11901    }
11902
11903    private static String processClass(ProcessRecord process) {
11904        if (process == null || process.pid == MY_PID) {
11905            return "system_server";
11906        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11907            return "system_app";
11908        } else {
11909            return "data_app";
11910        }
11911    }
11912
11913    /**
11914     * Write a description of an error (crash, WTF, ANR) to the drop box.
11915     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11916     * @param process which caused the error, null means the system server
11917     * @param activity which triggered the error, null if unknown
11918     * @param parent activity related to the error, null if unknown
11919     * @param subject line related to the error, null if absent
11920     * @param report in long form describing the error, null if absent
11921     * @param logFile to include in the report, null if none
11922     * @param crashInfo giving an application stack trace, null if absent
11923     */
11924    public void addErrorToDropBox(String eventType,
11925            ProcessRecord process, String processName, ActivityRecord activity,
11926            ActivityRecord parent, String subject,
11927            final String report, final File logFile,
11928            final ApplicationErrorReport.CrashInfo crashInfo) {
11929        // NOTE -- this must never acquire the ActivityManagerService lock,
11930        // otherwise the watchdog may be prevented from resetting the system.
11931
11932        final String dropboxTag = processClass(process) + "_" + eventType;
11933        final DropBoxManager dbox = (DropBoxManager)
11934                mContext.getSystemService(Context.DROPBOX_SERVICE);
11935
11936        // Exit early if the dropbox isn't configured to accept this report type.
11937        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11938
11939        final StringBuilder sb = new StringBuilder(1024);
11940        appendDropBoxProcessHeaders(process, processName, sb);
11941        if (activity != null) {
11942            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11943        }
11944        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11945            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11946        }
11947        if (parent != null && parent != activity) {
11948            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11949        }
11950        if (subject != null) {
11951            sb.append("Subject: ").append(subject).append("\n");
11952        }
11953        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11954        if (Debug.isDebuggerConnected()) {
11955            sb.append("Debugger: Connected\n");
11956        }
11957        sb.append("\n");
11958
11959        // Do the rest in a worker thread to avoid blocking the caller on I/O
11960        // (After this point, we shouldn't access AMS internal data structures.)
11961        Thread worker = new Thread("Error dump: " + dropboxTag) {
11962            @Override
11963            public void run() {
11964                if (report != null) {
11965                    sb.append(report);
11966                }
11967                if (logFile != null) {
11968                    try {
11969                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11970                                    "\n\n[[TRUNCATED]]"));
11971                    } catch (IOException e) {
11972                        Slog.e(TAG, "Error reading " + logFile, e);
11973                    }
11974                }
11975                if (crashInfo != null && crashInfo.stackTrace != null) {
11976                    sb.append(crashInfo.stackTrace);
11977                }
11978
11979                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11980                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11981                if (lines > 0) {
11982                    sb.append("\n");
11983
11984                    // Merge several logcat streams, and take the last N lines
11985                    InputStreamReader input = null;
11986                    try {
11987                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11988                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11989                                "-b", "crash",
11990                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11991
11992                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11993                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11994                        input = new InputStreamReader(logcat.getInputStream());
11995
11996                        int num;
11997                        char[] buf = new char[8192];
11998                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11999                    } catch (IOException e) {
12000                        Slog.e(TAG, "Error running logcat", e);
12001                    } finally {
12002                        if (input != null) try { input.close(); } catch (IOException e) {}
12003                    }
12004                }
12005
12006                dbox.addText(dropboxTag, sb.toString());
12007            }
12008        };
12009
12010        if (process == null) {
12011            // If process is null, we are being called from some internal code
12012            // and may be about to die -- run this synchronously.
12013            worker.run();
12014        } else {
12015            worker.start();
12016        }
12017    }
12018
12019    /**
12020     * Bring up the "unexpected error" dialog box for a crashing app.
12021     * Deal with edge cases (intercepts from instrumented applications,
12022     * ActivityController, error intent receivers, that sort of thing).
12023     * @param r the application crashing
12024     * @param crashInfo describing the failure
12025     */
12026    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12027        long timeMillis = System.currentTimeMillis();
12028        String shortMsg = crashInfo.exceptionClassName;
12029        String longMsg = crashInfo.exceptionMessage;
12030        String stackTrace = crashInfo.stackTrace;
12031        if (shortMsg != null && longMsg != null) {
12032            longMsg = shortMsg + ": " + longMsg;
12033        } else if (shortMsg != null) {
12034            longMsg = shortMsg;
12035        }
12036
12037        AppErrorResult result = new AppErrorResult();
12038        synchronized (this) {
12039            if (mController != null) {
12040                try {
12041                    String name = r != null ? r.processName : null;
12042                    int pid = r != null ? r.pid : Binder.getCallingPid();
12043                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
12044                    if (!mController.appCrashed(name, pid,
12045                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12046                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12047                                && "Native crash".equals(crashInfo.exceptionClassName)) {
12048                            Slog.w(TAG, "Skip killing native crashed app " + name
12049                                    + "(" + pid + ") during testing");
12050                        } else {
12051                            Slog.w(TAG, "Force-killing crashed app " + name
12052                                    + " at watcher's request");
12053                            if (r != null) {
12054                                r.kill("crash", true);
12055                            } else {
12056                                // Huh.
12057                                Process.killProcess(pid);
12058                                Process.killProcessGroup(uid, pid);
12059                            }
12060                        }
12061                        return;
12062                    }
12063                } catch (RemoteException e) {
12064                    mController = null;
12065                    Watchdog.getInstance().setActivityController(null);
12066                }
12067            }
12068
12069            final long origId = Binder.clearCallingIdentity();
12070
12071            // If this process is running instrumentation, finish it.
12072            if (r != null && r.instrumentationClass != null) {
12073                Slog.w(TAG, "Error in app " + r.processName
12074                      + " running instrumentation " + r.instrumentationClass + ":");
12075                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12076                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12077                Bundle info = new Bundle();
12078                info.putString("shortMsg", shortMsg);
12079                info.putString("longMsg", longMsg);
12080                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12081                Binder.restoreCallingIdentity(origId);
12082                return;
12083            }
12084
12085            // If we can't identify the process or it's already exceeded its crash quota,
12086            // quit right away without showing a crash dialog.
12087            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12088                Binder.restoreCallingIdentity(origId);
12089                return;
12090            }
12091
12092            Message msg = Message.obtain();
12093            msg.what = SHOW_ERROR_MSG;
12094            HashMap data = new HashMap();
12095            data.put("result", result);
12096            data.put("app", r);
12097            msg.obj = data;
12098            mHandler.sendMessage(msg);
12099
12100            Binder.restoreCallingIdentity(origId);
12101        }
12102
12103        int res = result.get();
12104
12105        Intent appErrorIntent = null;
12106        synchronized (this) {
12107            if (r != null && !r.isolated) {
12108                // XXX Can't keep track of crash time for isolated processes,
12109                // since they don't have a persistent identity.
12110                mProcessCrashTimes.put(r.info.processName, r.uid,
12111                        SystemClock.uptimeMillis());
12112            }
12113            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12114                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12115            }
12116        }
12117
12118        if (appErrorIntent != null) {
12119            try {
12120                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12121            } catch (ActivityNotFoundException e) {
12122                Slog.w(TAG, "bug report receiver dissappeared", e);
12123            }
12124        }
12125    }
12126
12127    Intent createAppErrorIntentLocked(ProcessRecord r,
12128            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12129        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12130        if (report == null) {
12131            return null;
12132        }
12133        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12134        result.setComponent(r.errorReportReceiver);
12135        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12136        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12137        return result;
12138    }
12139
12140    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12141            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12142        if (r.errorReportReceiver == null) {
12143            return null;
12144        }
12145
12146        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12147            return null;
12148        }
12149
12150        ApplicationErrorReport report = new ApplicationErrorReport();
12151        report.packageName = r.info.packageName;
12152        report.installerPackageName = r.errorReportReceiver.getPackageName();
12153        report.processName = r.processName;
12154        report.time = timeMillis;
12155        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12156
12157        if (r.crashing || r.forceCrashReport) {
12158            report.type = ApplicationErrorReport.TYPE_CRASH;
12159            report.crashInfo = crashInfo;
12160        } else if (r.notResponding) {
12161            report.type = ApplicationErrorReport.TYPE_ANR;
12162            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12163
12164            report.anrInfo.activity = r.notRespondingReport.tag;
12165            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12166            report.anrInfo.info = r.notRespondingReport.longMsg;
12167        }
12168
12169        return report;
12170    }
12171
12172    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12173        enforceNotIsolatedCaller("getProcessesInErrorState");
12174        // assume our apps are happy - lazy create the list
12175        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12176
12177        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12178                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12179        int userId = UserHandle.getUserId(Binder.getCallingUid());
12180
12181        synchronized (this) {
12182
12183            // iterate across all processes
12184            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12185                ProcessRecord app = mLruProcesses.get(i);
12186                if (!allUsers && app.userId != userId) {
12187                    continue;
12188                }
12189                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12190                    // This one's in trouble, so we'll generate a report for it
12191                    // crashes are higher priority (in case there's a crash *and* an anr)
12192                    ActivityManager.ProcessErrorStateInfo report = null;
12193                    if (app.crashing) {
12194                        report = app.crashingReport;
12195                    } else if (app.notResponding) {
12196                        report = app.notRespondingReport;
12197                    }
12198
12199                    if (report != null) {
12200                        if (errList == null) {
12201                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12202                        }
12203                        errList.add(report);
12204                    } else {
12205                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12206                                " crashing = " + app.crashing +
12207                                " notResponding = " + app.notResponding);
12208                    }
12209                }
12210            }
12211        }
12212
12213        return errList;
12214    }
12215
12216    static int procStateToImportance(int procState, int memAdj,
12217            ActivityManager.RunningAppProcessInfo currApp) {
12218        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12219        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12220            currApp.lru = memAdj;
12221        } else {
12222            currApp.lru = 0;
12223        }
12224        return imp;
12225    }
12226
12227    private void fillInProcMemInfo(ProcessRecord app,
12228            ActivityManager.RunningAppProcessInfo outInfo) {
12229        outInfo.pid = app.pid;
12230        outInfo.uid = app.info.uid;
12231        if (mHeavyWeightProcess == app) {
12232            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12233        }
12234        if (app.persistent) {
12235            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12236        }
12237        if (app.activities.size() > 0) {
12238            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12239        }
12240        outInfo.lastTrimLevel = app.trimMemoryLevel;
12241        int adj = app.curAdj;
12242        int procState = app.curProcState;
12243        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12244        outInfo.importanceReasonCode = app.adjTypeCode;
12245        outInfo.processState = app.curProcState;
12246    }
12247
12248    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12249        enforceNotIsolatedCaller("getRunningAppProcesses");
12250        // Lazy instantiation of list
12251        List<ActivityManager.RunningAppProcessInfo> runList = null;
12252        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12253                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12254        int userId = UserHandle.getUserId(Binder.getCallingUid());
12255        synchronized (this) {
12256            // Iterate across all processes
12257            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12258                ProcessRecord app = mLruProcesses.get(i);
12259                if (!allUsers && app.userId != userId) {
12260                    continue;
12261                }
12262                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12263                    // Generate process state info for running application
12264                    ActivityManager.RunningAppProcessInfo currApp =
12265                        new ActivityManager.RunningAppProcessInfo(app.processName,
12266                                app.pid, app.getPackageList());
12267                    fillInProcMemInfo(app, currApp);
12268                    if (app.adjSource instanceof ProcessRecord) {
12269                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12270                        currApp.importanceReasonImportance =
12271                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12272                                        app.adjSourceProcState);
12273                    } else if (app.adjSource instanceof ActivityRecord) {
12274                        ActivityRecord r = (ActivityRecord)app.adjSource;
12275                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12276                    }
12277                    if (app.adjTarget instanceof ComponentName) {
12278                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12279                    }
12280                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12281                    //        + " lru=" + currApp.lru);
12282                    if (runList == null) {
12283                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12284                    }
12285                    runList.add(currApp);
12286                }
12287            }
12288        }
12289        return runList;
12290    }
12291
12292    public List<ApplicationInfo> getRunningExternalApplications() {
12293        enforceNotIsolatedCaller("getRunningExternalApplications");
12294        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12295        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12296        if (runningApps != null && runningApps.size() > 0) {
12297            Set<String> extList = new HashSet<String>();
12298            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12299                if (app.pkgList != null) {
12300                    for (String pkg : app.pkgList) {
12301                        extList.add(pkg);
12302                    }
12303                }
12304            }
12305            IPackageManager pm = AppGlobals.getPackageManager();
12306            for (String pkg : extList) {
12307                try {
12308                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12309                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12310                        retList.add(info);
12311                    }
12312                } catch (RemoteException e) {
12313                }
12314            }
12315        }
12316        return retList;
12317    }
12318
12319    @Override
12320    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12321        enforceNotIsolatedCaller("getMyMemoryState");
12322        synchronized (this) {
12323            ProcessRecord proc;
12324            synchronized (mPidsSelfLocked) {
12325                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12326            }
12327            fillInProcMemInfo(proc, outInfo);
12328        }
12329    }
12330
12331    @Override
12332    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12333        if (checkCallingPermission(android.Manifest.permission.DUMP)
12334                != PackageManager.PERMISSION_GRANTED) {
12335            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12336                    + Binder.getCallingPid()
12337                    + ", uid=" + Binder.getCallingUid()
12338                    + " without permission "
12339                    + android.Manifest.permission.DUMP);
12340            return;
12341        }
12342
12343        boolean dumpAll = false;
12344        boolean dumpClient = false;
12345        String dumpPackage = null;
12346
12347        int opti = 0;
12348        while (opti < args.length) {
12349            String opt = args[opti];
12350            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12351                break;
12352            }
12353            opti++;
12354            if ("-a".equals(opt)) {
12355                dumpAll = true;
12356            } else if ("-c".equals(opt)) {
12357                dumpClient = true;
12358            } else if ("-h".equals(opt)) {
12359                pw.println("Activity manager dump options:");
12360                pw.println("  [-a] [-c] [-h] [cmd] ...");
12361                pw.println("  cmd may be one of:");
12362                pw.println("    a[ctivities]: activity stack state");
12363                pw.println("    r[recents]: recent activities state");
12364                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12365                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12366                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12367                pw.println("    o[om]: out of memory management");
12368                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12369                pw.println("    provider [COMP_SPEC]: provider client-side state");
12370                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12371                pw.println("    service [COMP_SPEC]: service client-side state");
12372                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12373                pw.println("    all: dump all activities");
12374                pw.println("    top: dump the top activity");
12375                pw.println("    write: write all pending state to storage");
12376                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12377                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12378                pw.println("    a partial substring in a component name, a");
12379                pw.println("    hex object identifier.");
12380                pw.println("  -a: include all available server state.");
12381                pw.println("  -c: include client state.");
12382                return;
12383            } else {
12384                pw.println("Unknown argument: " + opt + "; use -h for help");
12385            }
12386        }
12387
12388        long origId = Binder.clearCallingIdentity();
12389        boolean more = false;
12390        // Is the caller requesting to dump a particular piece of data?
12391        if (opti < args.length) {
12392            String cmd = args[opti];
12393            opti++;
12394            if ("activities".equals(cmd) || "a".equals(cmd)) {
12395                synchronized (this) {
12396                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12397                }
12398            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12399                synchronized (this) {
12400                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12401                }
12402            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12403                String[] newArgs;
12404                String name;
12405                if (opti >= args.length) {
12406                    name = null;
12407                    newArgs = EMPTY_STRING_ARRAY;
12408                } else {
12409                    name = args[opti];
12410                    opti++;
12411                    newArgs = new String[args.length - opti];
12412                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12413                            args.length - opti);
12414                }
12415                synchronized (this) {
12416                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12417                }
12418            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12419                String[] newArgs;
12420                String name;
12421                if (opti >= args.length) {
12422                    name = null;
12423                    newArgs = EMPTY_STRING_ARRAY;
12424                } else {
12425                    name = args[opti];
12426                    opti++;
12427                    newArgs = new String[args.length - opti];
12428                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12429                            args.length - opti);
12430                }
12431                synchronized (this) {
12432                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12433                }
12434            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12435                String[] newArgs;
12436                String name;
12437                if (opti >= args.length) {
12438                    name = null;
12439                    newArgs = EMPTY_STRING_ARRAY;
12440                } else {
12441                    name = args[opti];
12442                    opti++;
12443                    newArgs = new String[args.length - opti];
12444                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12445                            args.length - opti);
12446                }
12447                synchronized (this) {
12448                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12449                }
12450            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12451                synchronized (this) {
12452                    dumpOomLocked(fd, pw, args, opti, true);
12453                }
12454            } else if ("provider".equals(cmd)) {
12455                String[] newArgs;
12456                String name;
12457                if (opti >= args.length) {
12458                    name = null;
12459                    newArgs = EMPTY_STRING_ARRAY;
12460                } else {
12461                    name = args[opti];
12462                    opti++;
12463                    newArgs = new String[args.length - opti];
12464                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12465                }
12466                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12467                    pw.println("No providers match: " + name);
12468                    pw.println("Use -h for help.");
12469                }
12470            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12471                synchronized (this) {
12472                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12473                }
12474            } else if ("service".equals(cmd)) {
12475                String[] newArgs;
12476                String name;
12477                if (opti >= args.length) {
12478                    name = null;
12479                    newArgs = EMPTY_STRING_ARRAY;
12480                } else {
12481                    name = args[opti];
12482                    opti++;
12483                    newArgs = new String[args.length - opti];
12484                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12485                            args.length - opti);
12486                }
12487                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12488                    pw.println("No services match: " + name);
12489                    pw.println("Use -h for help.");
12490                }
12491            } else if ("package".equals(cmd)) {
12492                String[] newArgs;
12493                if (opti >= args.length) {
12494                    pw.println("package: no package name specified");
12495                    pw.println("Use -h for help.");
12496                } else {
12497                    dumpPackage = args[opti];
12498                    opti++;
12499                    newArgs = new String[args.length - opti];
12500                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12501                            args.length - opti);
12502                    args = newArgs;
12503                    opti = 0;
12504                    more = true;
12505                }
12506            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12507                synchronized (this) {
12508                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12509                }
12510            } else if ("write".equals(cmd)) {
12511                mTaskPersister.flush();
12512                pw.println("All tasks persisted.");
12513                return;
12514            } else {
12515                // Dumping a single activity?
12516                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12517                    pw.println("Bad activity command, or no activities match: " + cmd);
12518                    pw.println("Use -h for help.");
12519                }
12520            }
12521            if (!more) {
12522                Binder.restoreCallingIdentity(origId);
12523                return;
12524            }
12525        }
12526
12527        // No piece of data specified, dump everything.
12528        synchronized (this) {
12529            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12530            pw.println();
12531            if (dumpAll) {
12532                pw.println("-------------------------------------------------------------------------------");
12533            }
12534            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12535            pw.println();
12536            if (dumpAll) {
12537                pw.println("-------------------------------------------------------------------------------");
12538            }
12539            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12540            pw.println();
12541            if (dumpAll) {
12542                pw.println("-------------------------------------------------------------------------------");
12543            }
12544            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12545            pw.println();
12546            if (dumpAll) {
12547                pw.println("-------------------------------------------------------------------------------");
12548            }
12549            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12550            pw.println();
12551            if (dumpAll) {
12552                pw.println("-------------------------------------------------------------------------------");
12553            }
12554            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12555            pw.println();
12556            if (dumpAll) {
12557                pw.println("-------------------------------------------------------------------------------");
12558            }
12559            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12560        }
12561        Binder.restoreCallingIdentity(origId);
12562    }
12563
12564    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12565            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12566        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12567
12568        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12569                dumpPackage);
12570        boolean needSep = printedAnything;
12571
12572        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12573                dumpPackage, needSep, "  mFocusedActivity: ");
12574        if (printed) {
12575            printedAnything = true;
12576            needSep = false;
12577        }
12578
12579        if (dumpPackage == null) {
12580            if (needSep) {
12581                pw.println();
12582            }
12583            needSep = true;
12584            printedAnything = true;
12585            mStackSupervisor.dump(pw, "  ");
12586        }
12587
12588        if (!printedAnything) {
12589            pw.println("  (nothing)");
12590        }
12591    }
12592
12593    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12594            int opti, boolean dumpAll, String dumpPackage) {
12595        pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12596
12597        boolean printedAnything = false;
12598
12599        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12600            boolean printedHeader = false;
12601
12602            final int N = mRecentTasks.size();
12603            for (int i=0; i<N; i++) {
12604                TaskRecord tr = mRecentTasks.get(i);
12605                if (dumpPackage != null) {
12606                    if (tr.realActivity == null ||
12607                            !dumpPackage.equals(tr.realActivity)) {
12608                        continue;
12609                    }
12610                }
12611                if (!printedHeader) {
12612                    pw.println("  Recent tasks:");
12613                    printedHeader = true;
12614                    printedAnything = true;
12615                }
12616                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12617                        pw.println(tr);
12618                if (dumpAll) {
12619                    mRecentTasks.get(i).dump(pw, "    ");
12620                }
12621            }
12622        }
12623
12624        if (!printedAnything) {
12625            pw.println("  (nothing)");
12626        }
12627    }
12628
12629    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12630            int opti, boolean dumpAll, String dumpPackage) {
12631        boolean needSep = false;
12632        boolean printedAnything = false;
12633        int numPers = 0;
12634
12635        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12636
12637        if (dumpAll) {
12638            final int NP = mProcessNames.getMap().size();
12639            for (int ip=0; ip<NP; ip++) {
12640                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12641                final int NA = procs.size();
12642                for (int ia=0; ia<NA; ia++) {
12643                    ProcessRecord r = procs.valueAt(ia);
12644                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12645                        continue;
12646                    }
12647                    if (!needSep) {
12648                        pw.println("  All known processes:");
12649                        needSep = true;
12650                        printedAnything = true;
12651                    }
12652                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12653                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12654                        pw.print(" "); pw.println(r);
12655                    r.dump(pw, "    ");
12656                    if (r.persistent) {
12657                        numPers++;
12658                    }
12659                }
12660            }
12661        }
12662
12663        if (mIsolatedProcesses.size() > 0) {
12664            boolean printed = false;
12665            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12666                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12667                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12668                    continue;
12669                }
12670                if (!printed) {
12671                    if (needSep) {
12672                        pw.println();
12673                    }
12674                    pw.println("  Isolated process list (sorted by uid):");
12675                    printedAnything = true;
12676                    printed = true;
12677                    needSep = true;
12678                }
12679                pw.println(String.format("%sIsolated #%2d: %s",
12680                        "    ", i, r.toString()));
12681            }
12682        }
12683
12684        if (mLruProcesses.size() > 0) {
12685            if (needSep) {
12686                pw.println();
12687            }
12688            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12689                    pw.print(" total, non-act at ");
12690                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12691                    pw.print(", non-svc at ");
12692                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12693                    pw.println("):");
12694            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12695            needSep = true;
12696            printedAnything = true;
12697        }
12698
12699        if (dumpAll || dumpPackage != null) {
12700            synchronized (mPidsSelfLocked) {
12701                boolean printed = false;
12702                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12703                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12704                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12705                        continue;
12706                    }
12707                    if (!printed) {
12708                        if (needSep) pw.println();
12709                        needSep = true;
12710                        pw.println("  PID mappings:");
12711                        printed = true;
12712                        printedAnything = true;
12713                    }
12714                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12715                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12716                }
12717            }
12718        }
12719
12720        if (mForegroundProcesses.size() > 0) {
12721            synchronized (mPidsSelfLocked) {
12722                boolean printed = false;
12723                for (int i=0; i<mForegroundProcesses.size(); i++) {
12724                    ProcessRecord r = mPidsSelfLocked.get(
12725                            mForegroundProcesses.valueAt(i).pid);
12726                    if (dumpPackage != null && (r == null
12727                            || !r.pkgList.containsKey(dumpPackage))) {
12728                        continue;
12729                    }
12730                    if (!printed) {
12731                        if (needSep) pw.println();
12732                        needSep = true;
12733                        pw.println("  Foreground Processes:");
12734                        printed = true;
12735                        printedAnything = true;
12736                    }
12737                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12738                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12739                }
12740            }
12741        }
12742
12743        if (mPersistentStartingProcesses.size() > 0) {
12744            if (needSep) pw.println();
12745            needSep = true;
12746            printedAnything = true;
12747            pw.println("  Persisent processes that are starting:");
12748            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12749                    "Starting Norm", "Restarting PERS", dumpPackage);
12750        }
12751
12752        if (mRemovedProcesses.size() > 0) {
12753            if (needSep) pw.println();
12754            needSep = true;
12755            printedAnything = true;
12756            pw.println("  Processes that are being removed:");
12757            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12758                    "Removed Norm", "Removed PERS", dumpPackage);
12759        }
12760
12761        if (mProcessesOnHold.size() > 0) {
12762            if (needSep) pw.println();
12763            needSep = true;
12764            printedAnything = true;
12765            pw.println("  Processes that are on old until the system is ready:");
12766            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12767                    "OnHold Norm", "OnHold PERS", dumpPackage);
12768        }
12769
12770        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12771
12772        if (mProcessCrashTimes.getMap().size() > 0) {
12773            boolean printed = false;
12774            long now = SystemClock.uptimeMillis();
12775            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12776            final int NP = pmap.size();
12777            for (int ip=0; ip<NP; ip++) {
12778                String pname = pmap.keyAt(ip);
12779                SparseArray<Long> uids = pmap.valueAt(ip);
12780                final int N = uids.size();
12781                for (int i=0; i<N; i++) {
12782                    int puid = uids.keyAt(i);
12783                    ProcessRecord r = mProcessNames.get(pname, puid);
12784                    if (dumpPackage != null && (r == null
12785                            || !r.pkgList.containsKey(dumpPackage))) {
12786                        continue;
12787                    }
12788                    if (!printed) {
12789                        if (needSep) pw.println();
12790                        needSep = true;
12791                        pw.println("  Time since processes crashed:");
12792                        printed = true;
12793                        printedAnything = true;
12794                    }
12795                    pw.print("    Process "); pw.print(pname);
12796                            pw.print(" uid "); pw.print(puid);
12797                            pw.print(": last crashed ");
12798                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12799                            pw.println(" ago");
12800                }
12801            }
12802        }
12803
12804        if (mBadProcesses.getMap().size() > 0) {
12805            boolean printed = false;
12806            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12807            final int NP = pmap.size();
12808            for (int ip=0; ip<NP; ip++) {
12809                String pname = pmap.keyAt(ip);
12810                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12811                final int N = uids.size();
12812                for (int i=0; i<N; i++) {
12813                    int puid = uids.keyAt(i);
12814                    ProcessRecord r = mProcessNames.get(pname, puid);
12815                    if (dumpPackage != null && (r == null
12816                            || !r.pkgList.containsKey(dumpPackage))) {
12817                        continue;
12818                    }
12819                    if (!printed) {
12820                        if (needSep) pw.println();
12821                        needSep = true;
12822                        pw.println("  Bad processes:");
12823                        printedAnything = true;
12824                    }
12825                    BadProcessInfo info = uids.valueAt(i);
12826                    pw.print("    Bad process "); pw.print(pname);
12827                            pw.print(" uid "); pw.print(puid);
12828                            pw.print(": crashed at time "); pw.println(info.time);
12829                    if (info.shortMsg != null) {
12830                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12831                    }
12832                    if (info.longMsg != null) {
12833                        pw.print("      Long msg: "); pw.println(info.longMsg);
12834                    }
12835                    if (info.stack != null) {
12836                        pw.println("      Stack:");
12837                        int lastPos = 0;
12838                        for (int pos=0; pos<info.stack.length(); pos++) {
12839                            if (info.stack.charAt(pos) == '\n') {
12840                                pw.print("        ");
12841                                pw.write(info.stack, lastPos, pos-lastPos);
12842                                pw.println();
12843                                lastPos = pos+1;
12844                            }
12845                        }
12846                        if (lastPos < info.stack.length()) {
12847                            pw.print("        ");
12848                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12849                            pw.println();
12850                        }
12851                    }
12852                }
12853            }
12854        }
12855
12856        if (dumpPackage == null) {
12857            pw.println();
12858            needSep = false;
12859            pw.println("  mStartedUsers:");
12860            for (int i=0; i<mStartedUsers.size(); i++) {
12861                UserStartedState uss = mStartedUsers.valueAt(i);
12862                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12863                        pw.print(": "); uss.dump("", pw);
12864            }
12865            pw.print("  mStartedUserArray: [");
12866            for (int i=0; i<mStartedUserArray.length; i++) {
12867                if (i > 0) pw.print(", ");
12868                pw.print(mStartedUserArray[i]);
12869            }
12870            pw.println("]");
12871            pw.print("  mUserLru: [");
12872            for (int i=0; i<mUserLru.size(); i++) {
12873                if (i > 0) pw.print(", ");
12874                pw.print(mUserLru.get(i));
12875            }
12876            pw.println("]");
12877            if (dumpAll) {
12878                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12879            }
12880            synchronized (mUserProfileGroupIdsSelfLocked) {
12881                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12882                    pw.println("  mUserProfileGroupIds:");
12883                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12884                        pw.print("    User #");
12885                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12886                        pw.print(" -> profile #");
12887                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12888                    }
12889                }
12890            }
12891        }
12892        if (mHomeProcess != null && (dumpPackage == null
12893                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12894            if (needSep) {
12895                pw.println();
12896                needSep = false;
12897            }
12898            pw.println("  mHomeProcess: " + mHomeProcess);
12899        }
12900        if (mPreviousProcess != null && (dumpPackage == null
12901                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12902            if (needSep) {
12903                pw.println();
12904                needSep = false;
12905            }
12906            pw.println("  mPreviousProcess: " + mPreviousProcess);
12907        }
12908        if (dumpAll) {
12909            StringBuilder sb = new StringBuilder(128);
12910            sb.append("  mPreviousProcessVisibleTime: ");
12911            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12912            pw.println(sb);
12913        }
12914        if (mHeavyWeightProcess != null && (dumpPackage == null
12915                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12916            if (needSep) {
12917                pw.println();
12918                needSep = false;
12919            }
12920            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12921        }
12922        if (dumpPackage == null) {
12923            pw.println("  mConfiguration: " + mConfiguration);
12924        }
12925        if (dumpAll) {
12926            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12927            if (mCompatModePackages.getPackages().size() > 0) {
12928                boolean printed = false;
12929                for (Map.Entry<String, Integer> entry
12930                        : mCompatModePackages.getPackages().entrySet()) {
12931                    String pkg = entry.getKey();
12932                    int mode = entry.getValue();
12933                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12934                        continue;
12935                    }
12936                    if (!printed) {
12937                        pw.println("  mScreenCompatPackages:");
12938                        printed = true;
12939                    }
12940                    pw.print("    "); pw.print(pkg); pw.print(": ");
12941                            pw.print(mode); pw.println();
12942                }
12943            }
12944        }
12945        if (dumpPackage == null) {
12946            if (mSleeping || mWentToSleep || mLockScreenShown) {
12947                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12948                        + " mLockScreenShown " + mLockScreenShown);
12949            }
12950            if (mShuttingDown || mRunningVoice) {
12951                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12952            }
12953        }
12954        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12955                || mOrigWaitForDebugger) {
12956            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12957                    || dumpPackage.equals(mOrigDebugApp)) {
12958                if (needSep) {
12959                    pw.println();
12960                    needSep = false;
12961                }
12962                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12963                        + " mDebugTransient=" + mDebugTransient
12964                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12965            }
12966        }
12967        if (mOpenGlTraceApp != null) {
12968            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12969                if (needSep) {
12970                    pw.println();
12971                    needSep = false;
12972                }
12973                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12974            }
12975        }
12976        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12977                || mProfileFd != null) {
12978            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12979                if (needSep) {
12980                    pw.println();
12981                    needSep = false;
12982                }
12983                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12984                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12985                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12986                        + mAutoStopProfiler);
12987                pw.println("  mProfileType=" + mProfileType);
12988            }
12989        }
12990        if (dumpPackage == null) {
12991            if (mAlwaysFinishActivities || mController != null) {
12992                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12993                        + " mController=" + mController);
12994            }
12995            if (dumpAll) {
12996                pw.println("  Total persistent processes: " + numPers);
12997                pw.println("  mProcessesReady=" + mProcessesReady
12998                        + " mSystemReady=" + mSystemReady
12999                        + " mBooted=" + mBooted
13000                        + " mFactoryTest=" + mFactoryTest);
13001                pw.println("  mBooting=" + mBooting
13002                        + " mCallFinishBooting=" + mCallFinishBooting
13003                        + " mBootAnimationComplete=" + mBootAnimationComplete);
13004                pw.print("  mLastPowerCheckRealtime=");
13005                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13006                        pw.println("");
13007                pw.print("  mLastPowerCheckUptime=");
13008                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13009                        pw.println("");
13010                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13011                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13012                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13013                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
13014                        + " (" + mLruProcesses.size() + " total)"
13015                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13016                        + " mNumServiceProcs=" + mNumServiceProcs
13017                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13018                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
13019                        + " mLastMemoryLevel" + mLastMemoryLevel
13020                        + " mLastNumProcesses" + mLastNumProcesses);
13021                long now = SystemClock.uptimeMillis();
13022                pw.print("  mLastIdleTime=");
13023                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
13024                        pw.print(" mLowRamSinceLastIdle=");
13025                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13026                        pw.println();
13027            }
13028        }
13029
13030        if (!printedAnything) {
13031            pw.println("  (nothing)");
13032        }
13033    }
13034
13035    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13036            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13037        if (mProcessesToGc.size() > 0) {
13038            boolean printed = false;
13039            long now = SystemClock.uptimeMillis();
13040            for (int i=0; i<mProcessesToGc.size(); i++) {
13041                ProcessRecord proc = mProcessesToGc.get(i);
13042                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13043                    continue;
13044                }
13045                if (!printed) {
13046                    if (needSep) pw.println();
13047                    needSep = true;
13048                    pw.println("  Processes that are waiting to GC:");
13049                    printed = true;
13050                }
13051                pw.print("    Process "); pw.println(proc);
13052                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
13053                        pw.print(", last gced=");
13054                        pw.print(now-proc.lastRequestedGc);
13055                        pw.print(" ms ago, last lowMem=");
13056                        pw.print(now-proc.lastLowMemory);
13057                        pw.println(" ms ago");
13058
13059            }
13060        }
13061        return needSep;
13062    }
13063
13064    void printOomLevel(PrintWriter pw, String name, int adj) {
13065        pw.print("    ");
13066        if (adj >= 0) {
13067            pw.print(' ');
13068            if (adj < 10) pw.print(' ');
13069        } else {
13070            if (adj > -10) pw.print(' ');
13071        }
13072        pw.print(adj);
13073        pw.print(": ");
13074        pw.print(name);
13075        pw.print(" (");
13076        pw.print(mProcessList.getMemLevel(adj)/1024);
13077        pw.println(" kB)");
13078    }
13079
13080    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13081            int opti, boolean dumpAll) {
13082        boolean needSep = false;
13083
13084        if (mLruProcesses.size() > 0) {
13085            if (needSep) pw.println();
13086            needSep = true;
13087            pw.println("  OOM levels:");
13088            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13089            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13090            printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13091            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13092            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13093            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13094            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13095            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13096            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13097            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13098            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13099            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13100            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13101            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13102
13103            if (needSep) pw.println();
13104            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13105                    pw.print(" total, non-act at ");
13106                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13107                    pw.print(", non-svc at ");
13108                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13109                    pw.println("):");
13110            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13111            needSep = true;
13112        }
13113
13114        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13115
13116        pw.println();
13117        pw.println("  mHomeProcess: " + mHomeProcess);
13118        pw.println("  mPreviousProcess: " + mPreviousProcess);
13119        if (mHeavyWeightProcess != null) {
13120            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13121        }
13122
13123        return true;
13124    }
13125
13126    /**
13127     * There are three ways to call this:
13128     *  - no provider specified: dump all the providers
13129     *  - a flattened component name that matched an existing provider was specified as the
13130     *    first arg: dump that one provider
13131     *  - the first arg isn't the flattened component name of an existing provider:
13132     *    dump all providers whose component contains the first arg as a substring
13133     */
13134    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13135            int opti, boolean dumpAll) {
13136        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13137    }
13138
13139    static class ItemMatcher {
13140        ArrayList<ComponentName> components;
13141        ArrayList<String> strings;
13142        ArrayList<Integer> objects;
13143        boolean all;
13144
13145        ItemMatcher() {
13146            all = true;
13147        }
13148
13149        void build(String name) {
13150            ComponentName componentName = ComponentName.unflattenFromString(name);
13151            if (componentName != null) {
13152                if (components == null) {
13153                    components = new ArrayList<ComponentName>();
13154                }
13155                components.add(componentName);
13156                all = false;
13157            } else {
13158                int objectId = 0;
13159                // Not a '/' separated full component name; maybe an object ID?
13160                try {
13161                    objectId = Integer.parseInt(name, 16);
13162                    if (objects == null) {
13163                        objects = new ArrayList<Integer>();
13164                    }
13165                    objects.add(objectId);
13166                    all = false;
13167                } catch (RuntimeException e) {
13168                    // Not an integer; just do string match.
13169                    if (strings == null) {
13170                        strings = new ArrayList<String>();
13171                    }
13172                    strings.add(name);
13173                    all = false;
13174                }
13175            }
13176        }
13177
13178        int build(String[] args, int opti) {
13179            for (; opti<args.length; opti++) {
13180                String name = args[opti];
13181                if ("--".equals(name)) {
13182                    return opti+1;
13183                }
13184                build(name);
13185            }
13186            return opti;
13187        }
13188
13189        boolean match(Object object, ComponentName comp) {
13190            if (all) {
13191                return true;
13192            }
13193            if (components != null) {
13194                for (int i=0; i<components.size(); i++) {
13195                    if (components.get(i).equals(comp)) {
13196                        return true;
13197                    }
13198                }
13199            }
13200            if (objects != null) {
13201                for (int i=0; i<objects.size(); i++) {
13202                    if (System.identityHashCode(object) == objects.get(i)) {
13203                        return true;
13204                    }
13205                }
13206            }
13207            if (strings != null) {
13208                String flat = comp.flattenToString();
13209                for (int i=0; i<strings.size(); i++) {
13210                    if (flat.contains(strings.get(i))) {
13211                        return true;
13212                    }
13213                }
13214            }
13215            return false;
13216        }
13217    }
13218
13219    /**
13220     * There are three things that cmd can be:
13221     *  - a flattened component name that matches an existing activity
13222     *  - the cmd arg isn't the flattened component name of an existing activity:
13223     *    dump all activity whose component contains the cmd as a substring
13224     *  - A hex number of the ActivityRecord object instance.
13225     */
13226    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13227            int opti, boolean dumpAll) {
13228        ArrayList<ActivityRecord> activities;
13229
13230        synchronized (this) {
13231            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13232        }
13233
13234        if (activities.size() <= 0) {
13235            return false;
13236        }
13237
13238        String[] newArgs = new String[args.length - opti];
13239        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13240
13241        TaskRecord lastTask = null;
13242        boolean needSep = false;
13243        for (int i=activities.size()-1; i>=0; i--) {
13244            ActivityRecord r = activities.get(i);
13245            if (needSep) {
13246                pw.println();
13247            }
13248            needSep = true;
13249            synchronized (this) {
13250                if (lastTask != r.task) {
13251                    lastTask = r.task;
13252                    pw.print("TASK "); pw.print(lastTask.affinity);
13253                            pw.print(" id="); pw.println(lastTask.taskId);
13254                    if (dumpAll) {
13255                        lastTask.dump(pw, "  ");
13256                    }
13257                }
13258            }
13259            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13260        }
13261        return true;
13262    }
13263
13264    /**
13265     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13266     * there is a thread associated with the activity.
13267     */
13268    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13269            final ActivityRecord r, String[] args, boolean dumpAll) {
13270        String innerPrefix = prefix + "  ";
13271        synchronized (this) {
13272            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13273                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13274                    pw.print(" pid=");
13275                    if (r.app != null) pw.println(r.app.pid);
13276                    else pw.println("(not running)");
13277            if (dumpAll) {
13278                r.dump(pw, innerPrefix);
13279            }
13280        }
13281        if (r.app != null && r.app.thread != null) {
13282            // flush anything that is already in the PrintWriter since the thread is going
13283            // to write to the file descriptor directly
13284            pw.flush();
13285            try {
13286                TransferPipe tp = new TransferPipe();
13287                try {
13288                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13289                            r.appToken, innerPrefix, args);
13290                    tp.go(fd);
13291                } finally {
13292                    tp.kill();
13293                }
13294            } catch (IOException e) {
13295                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13296            } catch (RemoteException e) {
13297                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13298            }
13299        }
13300    }
13301
13302    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13303            int opti, boolean dumpAll, String dumpPackage) {
13304        boolean needSep = false;
13305        boolean onlyHistory = false;
13306        boolean printedAnything = false;
13307
13308        if ("history".equals(dumpPackage)) {
13309            if (opti < args.length && "-s".equals(args[opti])) {
13310                dumpAll = false;
13311            }
13312            onlyHistory = true;
13313            dumpPackage = null;
13314        }
13315
13316        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13317        if (!onlyHistory && dumpAll) {
13318            if (mRegisteredReceivers.size() > 0) {
13319                boolean printed = false;
13320                Iterator it = mRegisteredReceivers.values().iterator();
13321                while (it.hasNext()) {
13322                    ReceiverList r = (ReceiverList)it.next();
13323                    if (dumpPackage != null && (r.app == null ||
13324                            !dumpPackage.equals(r.app.info.packageName))) {
13325                        continue;
13326                    }
13327                    if (!printed) {
13328                        pw.println("  Registered Receivers:");
13329                        needSep = true;
13330                        printed = true;
13331                        printedAnything = true;
13332                    }
13333                    pw.print("  * "); pw.println(r);
13334                    r.dump(pw, "    ");
13335                }
13336            }
13337
13338            if (mReceiverResolver.dump(pw, needSep ?
13339                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13340                    "    ", dumpPackage, false)) {
13341                needSep = true;
13342                printedAnything = true;
13343            }
13344        }
13345
13346        for (BroadcastQueue q : mBroadcastQueues) {
13347            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13348            printedAnything |= needSep;
13349        }
13350
13351        needSep = true;
13352
13353        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13354            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13355                if (needSep) {
13356                    pw.println();
13357                }
13358                needSep = true;
13359                printedAnything = true;
13360                pw.print("  Sticky broadcasts for user ");
13361                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13362                StringBuilder sb = new StringBuilder(128);
13363                for (Map.Entry<String, ArrayList<Intent>> ent
13364                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13365                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13366                    if (dumpAll) {
13367                        pw.println(":");
13368                        ArrayList<Intent> intents = ent.getValue();
13369                        final int N = intents.size();
13370                        for (int i=0; i<N; i++) {
13371                            sb.setLength(0);
13372                            sb.append("    Intent: ");
13373                            intents.get(i).toShortString(sb, false, true, false, false);
13374                            pw.println(sb.toString());
13375                            Bundle bundle = intents.get(i).getExtras();
13376                            if (bundle != null) {
13377                                pw.print("      ");
13378                                pw.println(bundle.toString());
13379                            }
13380                        }
13381                    } else {
13382                        pw.println("");
13383                    }
13384                }
13385            }
13386        }
13387
13388        if (!onlyHistory && dumpAll) {
13389            pw.println();
13390            for (BroadcastQueue queue : mBroadcastQueues) {
13391                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13392                        + queue.mBroadcastsScheduled);
13393            }
13394            pw.println("  mHandler:");
13395            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13396            needSep = true;
13397            printedAnything = true;
13398        }
13399
13400        if (!printedAnything) {
13401            pw.println("  (nothing)");
13402        }
13403    }
13404
13405    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13406            int opti, boolean dumpAll, String dumpPackage) {
13407        boolean needSep;
13408        boolean printedAnything = false;
13409
13410        ItemMatcher matcher = new ItemMatcher();
13411        matcher.build(args, opti);
13412
13413        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13414
13415        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13416        printedAnything |= needSep;
13417
13418        if (mLaunchingProviders.size() > 0) {
13419            boolean printed = false;
13420            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13421                ContentProviderRecord r = mLaunchingProviders.get(i);
13422                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13423                    continue;
13424                }
13425                if (!printed) {
13426                    if (needSep) pw.println();
13427                    needSep = true;
13428                    pw.println("  Launching content providers:");
13429                    printed = true;
13430                    printedAnything = true;
13431                }
13432                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13433                        pw.println(r);
13434            }
13435        }
13436
13437        if (mGrantedUriPermissions.size() > 0) {
13438            boolean printed = false;
13439            int dumpUid = -2;
13440            if (dumpPackage != null) {
13441                try {
13442                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13443                } catch (NameNotFoundException e) {
13444                    dumpUid = -1;
13445                }
13446            }
13447            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13448                int uid = mGrantedUriPermissions.keyAt(i);
13449                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13450                    continue;
13451                }
13452                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13453                if (!printed) {
13454                    if (needSep) pw.println();
13455                    needSep = true;
13456                    pw.println("  Granted Uri Permissions:");
13457                    printed = true;
13458                    printedAnything = true;
13459                }
13460                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13461                for (UriPermission perm : perms.values()) {
13462                    pw.print("    "); pw.println(perm);
13463                    if (dumpAll) {
13464                        perm.dump(pw, "      ");
13465                    }
13466                }
13467            }
13468        }
13469
13470        if (!printedAnything) {
13471            pw.println("  (nothing)");
13472        }
13473    }
13474
13475    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13476            int opti, boolean dumpAll, String dumpPackage) {
13477        boolean printed = false;
13478
13479        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13480
13481        if (mIntentSenderRecords.size() > 0) {
13482            Iterator<WeakReference<PendingIntentRecord>> it
13483                    = mIntentSenderRecords.values().iterator();
13484            while (it.hasNext()) {
13485                WeakReference<PendingIntentRecord> ref = it.next();
13486                PendingIntentRecord rec = ref != null ? ref.get(): null;
13487                if (dumpPackage != null && (rec == null
13488                        || !dumpPackage.equals(rec.key.packageName))) {
13489                    continue;
13490                }
13491                printed = true;
13492                if (rec != null) {
13493                    pw.print("  * "); pw.println(rec);
13494                    if (dumpAll) {
13495                        rec.dump(pw, "    ");
13496                    }
13497                } else {
13498                    pw.print("  * "); pw.println(ref);
13499                }
13500            }
13501        }
13502
13503        if (!printed) {
13504            pw.println("  (nothing)");
13505        }
13506    }
13507
13508    private static final int dumpProcessList(PrintWriter pw,
13509            ActivityManagerService service, List list,
13510            String prefix, String normalLabel, String persistentLabel,
13511            String dumpPackage) {
13512        int numPers = 0;
13513        final int N = list.size()-1;
13514        for (int i=N; i>=0; i--) {
13515            ProcessRecord r = (ProcessRecord)list.get(i);
13516            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13517                continue;
13518            }
13519            pw.println(String.format("%s%s #%2d: %s",
13520                    prefix, (r.persistent ? persistentLabel : normalLabel),
13521                    i, r.toString()));
13522            if (r.persistent) {
13523                numPers++;
13524            }
13525        }
13526        return numPers;
13527    }
13528
13529    private static final boolean dumpProcessOomList(PrintWriter pw,
13530            ActivityManagerService service, List<ProcessRecord> origList,
13531            String prefix, String normalLabel, String persistentLabel,
13532            boolean inclDetails, String dumpPackage) {
13533
13534        ArrayList<Pair<ProcessRecord, Integer>> list
13535                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13536        for (int i=0; i<origList.size(); i++) {
13537            ProcessRecord r = origList.get(i);
13538            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13539                continue;
13540            }
13541            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13542        }
13543
13544        if (list.size() <= 0) {
13545            return false;
13546        }
13547
13548        Comparator<Pair<ProcessRecord, Integer>> comparator
13549                = new Comparator<Pair<ProcessRecord, Integer>>() {
13550            @Override
13551            public int compare(Pair<ProcessRecord, Integer> object1,
13552                    Pair<ProcessRecord, Integer> object2) {
13553                if (object1.first.setAdj != object2.first.setAdj) {
13554                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13555                }
13556                if (object1.second.intValue() != object2.second.intValue()) {
13557                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13558                }
13559                return 0;
13560            }
13561        };
13562
13563        Collections.sort(list, comparator);
13564
13565        final long curRealtime = SystemClock.elapsedRealtime();
13566        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13567        final long curUptime = SystemClock.uptimeMillis();
13568        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13569
13570        for (int i=list.size()-1; i>=0; i--) {
13571            ProcessRecord r = list.get(i).first;
13572            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13573            char schedGroup;
13574            switch (r.setSchedGroup) {
13575                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13576                    schedGroup = 'B';
13577                    break;
13578                case Process.THREAD_GROUP_DEFAULT:
13579                    schedGroup = 'F';
13580                    break;
13581                default:
13582                    schedGroup = '?';
13583                    break;
13584            }
13585            char foreground;
13586            if (r.foregroundActivities) {
13587                foreground = 'A';
13588            } else if (r.foregroundServices) {
13589                foreground = 'S';
13590            } else {
13591                foreground = ' ';
13592            }
13593            String procState = ProcessList.makeProcStateString(r.curProcState);
13594            pw.print(prefix);
13595            pw.print(r.persistent ? persistentLabel : normalLabel);
13596            pw.print(" #");
13597            int num = (origList.size()-1)-list.get(i).second;
13598            if (num < 10) pw.print(' ');
13599            pw.print(num);
13600            pw.print(": ");
13601            pw.print(oomAdj);
13602            pw.print(' ');
13603            pw.print(schedGroup);
13604            pw.print('/');
13605            pw.print(foreground);
13606            pw.print('/');
13607            pw.print(procState);
13608            pw.print(" trm:");
13609            if (r.trimMemoryLevel < 10) pw.print(' ');
13610            pw.print(r.trimMemoryLevel);
13611            pw.print(' ');
13612            pw.print(r.toShortString());
13613            pw.print(" (");
13614            pw.print(r.adjType);
13615            pw.println(')');
13616            if (r.adjSource != null || r.adjTarget != null) {
13617                pw.print(prefix);
13618                pw.print("    ");
13619                if (r.adjTarget instanceof ComponentName) {
13620                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13621                } else if (r.adjTarget != null) {
13622                    pw.print(r.adjTarget.toString());
13623                } else {
13624                    pw.print("{null}");
13625                }
13626                pw.print("<=");
13627                if (r.adjSource instanceof ProcessRecord) {
13628                    pw.print("Proc{");
13629                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13630                    pw.println("}");
13631                } else if (r.adjSource != null) {
13632                    pw.println(r.adjSource.toString());
13633                } else {
13634                    pw.println("{null}");
13635                }
13636            }
13637            if (inclDetails) {
13638                pw.print(prefix);
13639                pw.print("    ");
13640                pw.print("oom: max="); pw.print(r.maxAdj);
13641                pw.print(" curRaw="); pw.print(r.curRawAdj);
13642                pw.print(" setRaw="); pw.print(r.setRawAdj);
13643                pw.print(" cur="); pw.print(r.curAdj);
13644                pw.print(" set="); pw.println(r.setAdj);
13645                pw.print(prefix);
13646                pw.print("    ");
13647                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13648                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13649                pw.print(" lastPss="); pw.print(r.lastPss);
13650                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13651                pw.print(prefix);
13652                pw.print("    ");
13653                pw.print("cached="); pw.print(r.cached);
13654                pw.print(" empty="); pw.print(r.empty);
13655                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13656
13657                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13658                    if (r.lastWakeTime != 0) {
13659                        long wtime;
13660                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13661                        synchronized (stats) {
13662                            wtime = stats.getProcessWakeTime(r.info.uid,
13663                                    r.pid, curRealtime);
13664                        }
13665                        long timeUsed = wtime - r.lastWakeTime;
13666                        pw.print(prefix);
13667                        pw.print("    ");
13668                        pw.print("keep awake over ");
13669                        TimeUtils.formatDuration(realtimeSince, pw);
13670                        pw.print(" used ");
13671                        TimeUtils.formatDuration(timeUsed, pw);
13672                        pw.print(" (");
13673                        pw.print((timeUsed*100)/realtimeSince);
13674                        pw.println("%)");
13675                    }
13676                    if (r.lastCpuTime != 0) {
13677                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13678                        pw.print(prefix);
13679                        pw.print("    ");
13680                        pw.print("run cpu over ");
13681                        TimeUtils.formatDuration(uptimeSince, pw);
13682                        pw.print(" used ");
13683                        TimeUtils.formatDuration(timeUsed, pw);
13684                        pw.print(" (");
13685                        pw.print((timeUsed*100)/uptimeSince);
13686                        pw.println("%)");
13687                    }
13688                }
13689            }
13690        }
13691        return true;
13692    }
13693
13694    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13695            String[] args) {
13696        ArrayList<ProcessRecord> procs;
13697        synchronized (this) {
13698            if (args != null && args.length > start
13699                    && args[start].charAt(0) != '-') {
13700                procs = new ArrayList<ProcessRecord>();
13701                int pid = -1;
13702                try {
13703                    pid = Integer.parseInt(args[start]);
13704                } catch (NumberFormatException e) {
13705                }
13706                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13707                    ProcessRecord proc = mLruProcesses.get(i);
13708                    if (proc.pid == pid) {
13709                        procs.add(proc);
13710                    } else if (allPkgs && proc.pkgList != null
13711                            && proc.pkgList.containsKey(args[start])) {
13712                        procs.add(proc);
13713                    } else if (proc.processName.equals(args[start])) {
13714                        procs.add(proc);
13715                    }
13716                }
13717                if (procs.size() <= 0) {
13718                    return null;
13719                }
13720            } else {
13721                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13722            }
13723        }
13724        return procs;
13725    }
13726
13727    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13728            PrintWriter pw, String[] args) {
13729        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13730        if (procs == null) {
13731            pw.println("No process found for: " + args[0]);
13732            return;
13733        }
13734
13735        long uptime = SystemClock.uptimeMillis();
13736        long realtime = SystemClock.elapsedRealtime();
13737        pw.println("Applications Graphics Acceleration Info:");
13738        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13739
13740        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13741            ProcessRecord r = procs.get(i);
13742            if (r.thread != null) {
13743                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13744                pw.flush();
13745                try {
13746                    TransferPipe tp = new TransferPipe();
13747                    try {
13748                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13749                        tp.go(fd);
13750                    } finally {
13751                        tp.kill();
13752                    }
13753                } catch (IOException e) {
13754                    pw.println("Failure while dumping the app: " + r);
13755                    pw.flush();
13756                } catch (RemoteException e) {
13757                    pw.println("Got a RemoteException while dumping the app " + r);
13758                    pw.flush();
13759                }
13760            }
13761        }
13762    }
13763
13764    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13765        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13766        if (procs == null) {
13767            pw.println("No process found for: " + args[0]);
13768            return;
13769        }
13770
13771        pw.println("Applications Database Info:");
13772
13773        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13774            ProcessRecord r = procs.get(i);
13775            if (r.thread != null) {
13776                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13777                pw.flush();
13778                try {
13779                    TransferPipe tp = new TransferPipe();
13780                    try {
13781                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13782                        tp.go(fd);
13783                    } finally {
13784                        tp.kill();
13785                    }
13786                } catch (IOException e) {
13787                    pw.println("Failure while dumping the app: " + r);
13788                    pw.flush();
13789                } catch (RemoteException e) {
13790                    pw.println("Got a RemoteException while dumping the app " + r);
13791                    pw.flush();
13792                }
13793            }
13794        }
13795    }
13796
13797    final static class MemItem {
13798        final boolean isProc;
13799        final String label;
13800        final String shortLabel;
13801        final long pss;
13802        final int id;
13803        final boolean hasActivities;
13804        ArrayList<MemItem> subitems;
13805
13806        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13807                boolean _hasActivities) {
13808            isProc = true;
13809            label = _label;
13810            shortLabel = _shortLabel;
13811            pss = _pss;
13812            id = _id;
13813            hasActivities = _hasActivities;
13814        }
13815
13816        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13817            isProc = false;
13818            label = _label;
13819            shortLabel = _shortLabel;
13820            pss = _pss;
13821            id = _id;
13822            hasActivities = false;
13823        }
13824    }
13825
13826    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13827            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13828        if (sort && !isCompact) {
13829            Collections.sort(items, new Comparator<MemItem>() {
13830                @Override
13831                public int compare(MemItem lhs, MemItem rhs) {
13832                    if (lhs.pss < rhs.pss) {
13833                        return 1;
13834                    } else if (lhs.pss > rhs.pss) {
13835                        return -1;
13836                    }
13837                    return 0;
13838                }
13839            });
13840        }
13841
13842        for (int i=0; i<items.size(); i++) {
13843            MemItem mi = items.get(i);
13844            if (!isCompact) {
13845                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13846            } else if (mi.isProc) {
13847                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13848                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13849                pw.println(mi.hasActivities ? ",a" : ",e");
13850            } else {
13851                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13852                pw.println(mi.pss);
13853            }
13854            if (mi.subitems != null) {
13855                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13856                        true, isCompact);
13857            }
13858        }
13859    }
13860
13861    // These are in KB.
13862    static final long[] DUMP_MEM_BUCKETS = new long[] {
13863        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13864        120*1024, 160*1024, 200*1024,
13865        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13866        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13867    };
13868
13869    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13870            boolean stackLike) {
13871        int start = label.lastIndexOf('.');
13872        if (start >= 0) start++;
13873        else start = 0;
13874        int end = label.length();
13875        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13876            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13877                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13878                out.append(bucket);
13879                out.append(stackLike ? "MB." : "MB ");
13880                out.append(label, start, end);
13881                return;
13882            }
13883        }
13884        out.append(memKB/1024);
13885        out.append(stackLike ? "MB." : "MB ");
13886        out.append(label, start, end);
13887    }
13888
13889    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13890            ProcessList.NATIVE_ADJ,
13891            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13892            ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13893            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13894            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13895            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13896            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13897    };
13898    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13899            "Native",
13900            "System", "Persistent", "Persistent Service", "Foreground",
13901            "Visible", "Perceptible",
13902            "Heavy Weight", "Backup",
13903            "A Services", "Home",
13904            "Previous", "B Services", "Cached"
13905    };
13906    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13907            "native",
13908            "sys", "pers", "persvc", "fore",
13909            "vis", "percept",
13910            "heavy", "backup",
13911            "servicea", "home",
13912            "prev", "serviceb", "cached"
13913    };
13914
13915    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13916            long realtime, boolean isCheckinRequest, boolean isCompact) {
13917        if (isCheckinRequest || isCompact) {
13918            // short checkin version
13919            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13920        } else {
13921            pw.println("Applications Memory Usage (kB):");
13922            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13923        }
13924    }
13925
13926    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13927            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13928        boolean dumpDetails = false;
13929        boolean dumpFullDetails = false;
13930        boolean dumpDalvik = false;
13931        boolean oomOnly = false;
13932        boolean isCompact = false;
13933        boolean localOnly = false;
13934        boolean packages = false;
13935
13936        int opti = 0;
13937        while (opti < args.length) {
13938            String opt = args[opti];
13939            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13940                break;
13941            }
13942            opti++;
13943            if ("-a".equals(opt)) {
13944                dumpDetails = true;
13945                dumpFullDetails = true;
13946                dumpDalvik = true;
13947            } else if ("-d".equals(opt)) {
13948                dumpDalvik = true;
13949            } else if ("-c".equals(opt)) {
13950                isCompact = true;
13951            } else if ("--oom".equals(opt)) {
13952                oomOnly = true;
13953            } else if ("--local".equals(opt)) {
13954                localOnly = true;
13955            } else if ("--package".equals(opt)) {
13956                packages = true;
13957            } else if ("-h".equals(opt)) {
13958                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13959                pw.println("  -a: include all available information for each process.");
13960                pw.println("  -d: include dalvik details when dumping process details.");
13961                pw.println("  -c: dump in a compact machine-parseable representation.");
13962                pw.println("  --oom: only show processes organized by oom adj.");
13963                pw.println("  --local: only collect details locally, don't call process.");
13964                pw.println("  --package: interpret process arg as package, dumping all");
13965                pw.println("             processes that have loaded that package.");
13966                pw.println("If [process] is specified it can be the name or ");
13967                pw.println("pid of a specific process to dump.");
13968                return;
13969            } else {
13970                pw.println("Unknown argument: " + opt + "; use -h for help");
13971            }
13972        }
13973
13974        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13975        long uptime = SystemClock.uptimeMillis();
13976        long realtime = SystemClock.elapsedRealtime();
13977        final long[] tmpLong = new long[1];
13978
13979        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13980        if (procs == null) {
13981            // No Java processes.  Maybe they want to print a native process.
13982            if (args != null && args.length > opti
13983                    && args[opti].charAt(0) != '-') {
13984                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13985                        = new ArrayList<ProcessCpuTracker.Stats>();
13986                updateCpuStatsNow();
13987                int findPid = -1;
13988                try {
13989                    findPid = Integer.parseInt(args[opti]);
13990                } catch (NumberFormatException e) {
13991                }
13992                synchronized (mProcessCpuTracker) {
13993                    final int N = mProcessCpuTracker.countStats();
13994                    for (int i=0; i<N; i++) {
13995                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13996                        if (st.pid == findPid || (st.baseName != null
13997                                && st.baseName.equals(args[opti]))) {
13998                            nativeProcs.add(st);
13999                        }
14000                    }
14001                }
14002                if (nativeProcs.size() > 0) {
14003                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14004                            isCompact);
14005                    Debug.MemoryInfo mi = null;
14006                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14007                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14008                        final int pid = r.pid;
14009                        if (!isCheckinRequest && dumpDetails) {
14010                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14011                        }
14012                        if (mi == null) {
14013                            mi = new Debug.MemoryInfo();
14014                        }
14015                        if (dumpDetails || (!brief && !oomOnly)) {
14016                            Debug.getMemoryInfo(pid, mi);
14017                        } else {
14018                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14019                            mi.dalvikPrivateDirty = (int)tmpLong[0];
14020                        }
14021                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14022                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14023                        if (isCheckinRequest) {
14024                            pw.println();
14025                        }
14026                    }
14027                    return;
14028                }
14029            }
14030            pw.println("No process found for: " + args[opti]);
14031            return;
14032        }
14033
14034        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14035            dumpDetails = true;
14036        }
14037
14038        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14039
14040        String[] innerArgs = new String[args.length-opti];
14041        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14042
14043        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14044        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14045        long nativePss=0, dalvikPss=0, otherPss=0;
14046        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14047
14048        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14049        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14050                new ArrayList[DUMP_MEM_OOM_LABEL.length];
14051
14052        long totalPss = 0;
14053        long cachedPss = 0;
14054
14055        Debug.MemoryInfo mi = null;
14056        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14057            final ProcessRecord r = procs.get(i);
14058            final IApplicationThread thread;
14059            final int pid;
14060            final int oomAdj;
14061            final boolean hasActivities;
14062            synchronized (this) {
14063                thread = r.thread;
14064                pid = r.pid;
14065                oomAdj = r.getSetAdjWithServices();
14066                hasActivities = r.activities.size() > 0;
14067            }
14068            if (thread != null) {
14069                if (!isCheckinRequest && dumpDetails) {
14070                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14071                }
14072                if (mi == null) {
14073                    mi = new Debug.MemoryInfo();
14074                }
14075                if (dumpDetails || (!brief && !oomOnly)) {
14076                    Debug.getMemoryInfo(pid, mi);
14077                } else {
14078                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14079                    mi.dalvikPrivateDirty = (int)tmpLong[0];
14080                }
14081                if (dumpDetails) {
14082                    if (localOnly) {
14083                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14084                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14085                        if (isCheckinRequest) {
14086                            pw.println();
14087                        }
14088                    } else {
14089                        try {
14090                            pw.flush();
14091                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14092                                    dumpDalvik, innerArgs);
14093                        } catch (RemoteException e) {
14094                            if (!isCheckinRequest) {
14095                                pw.println("Got RemoteException!");
14096                                pw.flush();
14097                            }
14098                        }
14099                    }
14100                }
14101
14102                final long myTotalPss = mi.getTotalPss();
14103                final long myTotalUss = mi.getTotalUss();
14104
14105                synchronized (this) {
14106                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14107                        // Record this for posterity if the process has been stable.
14108                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14109                    }
14110                }
14111
14112                if (!isCheckinRequest && mi != null) {
14113                    totalPss += myTotalPss;
14114                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14115                            (hasActivities ? " / activities)" : ")"),
14116                            r.processName, myTotalPss, pid, hasActivities);
14117                    procMems.add(pssItem);
14118                    procMemsMap.put(pid, pssItem);
14119
14120                    nativePss += mi.nativePss;
14121                    dalvikPss += mi.dalvikPss;
14122                    otherPss += mi.otherPss;
14123                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14124                        long mem = mi.getOtherPss(j);
14125                        miscPss[j] += mem;
14126                        otherPss -= mem;
14127                    }
14128
14129                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14130                        cachedPss += myTotalPss;
14131                    }
14132
14133                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14134                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14135                                || oomIndex == (oomPss.length-1)) {
14136                            oomPss[oomIndex] += myTotalPss;
14137                            if (oomProcs[oomIndex] == null) {
14138                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14139                            }
14140                            oomProcs[oomIndex].add(pssItem);
14141                            break;
14142                        }
14143                    }
14144                }
14145            }
14146        }
14147
14148        long nativeProcTotalPss = 0;
14149
14150        if (!isCheckinRequest && procs.size() > 1 && !packages) {
14151            // If we are showing aggregations, also look for native processes to
14152            // include so that our aggregations are more accurate.
14153            updateCpuStatsNow();
14154            synchronized (mProcessCpuTracker) {
14155                final int N = mProcessCpuTracker.countStats();
14156                for (int i=0; i<N; i++) {
14157                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14158                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14159                        if (mi == null) {
14160                            mi = new Debug.MemoryInfo();
14161                        }
14162                        if (!brief && !oomOnly) {
14163                            Debug.getMemoryInfo(st.pid, mi);
14164                        } else {
14165                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14166                            mi.nativePrivateDirty = (int)tmpLong[0];
14167                        }
14168
14169                        final long myTotalPss = mi.getTotalPss();
14170                        totalPss += myTotalPss;
14171                        nativeProcTotalPss += myTotalPss;
14172
14173                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14174                                st.name, myTotalPss, st.pid, false);
14175                        procMems.add(pssItem);
14176
14177                        nativePss += mi.nativePss;
14178                        dalvikPss += mi.dalvikPss;
14179                        otherPss += mi.otherPss;
14180                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14181                            long mem = mi.getOtherPss(j);
14182                            miscPss[j] += mem;
14183                            otherPss -= mem;
14184                        }
14185                        oomPss[0] += myTotalPss;
14186                        if (oomProcs[0] == null) {
14187                            oomProcs[0] = new ArrayList<MemItem>();
14188                        }
14189                        oomProcs[0].add(pssItem);
14190                    }
14191                }
14192            }
14193
14194            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14195
14196            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14197            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14198            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14199            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14200                String label = Debug.MemoryInfo.getOtherLabel(j);
14201                catMems.add(new MemItem(label, label, miscPss[j], j));
14202            }
14203
14204            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14205            for (int j=0; j<oomPss.length; j++) {
14206                if (oomPss[j] != 0) {
14207                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14208                            : DUMP_MEM_OOM_LABEL[j];
14209                    MemItem item = new MemItem(label, label, oomPss[j],
14210                            DUMP_MEM_OOM_ADJ[j]);
14211                    item.subitems = oomProcs[j];
14212                    oomMems.add(item);
14213                }
14214            }
14215
14216            if (!brief && !oomOnly && !isCompact) {
14217                pw.println();
14218                pw.println("Total PSS by process:");
14219                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14220                pw.println();
14221            }
14222            if (!isCompact) {
14223                pw.println("Total PSS by OOM adjustment:");
14224            }
14225            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14226            if (!brief && !oomOnly) {
14227                PrintWriter out = categoryPw != null ? categoryPw : pw;
14228                if (!isCompact) {
14229                    out.println();
14230                    out.println("Total PSS by category:");
14231                }
14232                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14233            }
14234            if (!isCompact) {
14235                pw.println();
14236            }
14237            MemInfoReader memInfo = new MemInfoReader();
14238            memInfo.readMemInfo();
14239            if (nativeProcTotalPss > 0) {
14240                synchronized (this) {
14241                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14242                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14243                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14244                            nativeProcTotalPss);
14245                }
14246            }
14247            if (!brief) {
14248                if (!isCompact) {
14249                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14250                    pw.print(" kB (status ");
14251                    switch (mLastMemoryLevel) {
14252                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14253                            pw.println("normal)");
14254                            break;
14255                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14256                            pw.println("moderate)");
14257                            break;
14258                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14259                            pw.println("low)");
14260                            break;
14261                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14262                            pw.println("critical)");
14263                            break;
14264                        default:
14265                            pw.print(mLastMemoryLevel);
14266                            pw.println(")");
14267                            break;
14268                    }
14269                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14270                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14271                            pw.print(cachedPss); pw.print(" cached pss + ");
14272                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14273                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14274                } else {
14275                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14276                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14277                            + memInfo.getFreeSizeKb()); pw.print(",");
14278                    pw.println(totalPss - cachedPss);
14279                }
14280            }
14281            if (!isCompact) {
14282                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14283                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14284                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14285                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14286                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14287                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14288                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14289                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14290                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14291                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14292                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14293            }
14294            if (!brief) {
14295                if (memInfo.getZramTotalSizeKb() != 0) {
14296                    if (!isCompact) {
14297                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14298                                pw.print(" kB physical used for ");
14299                                pw.print(memInfo.getSwapTotalSizeKb()
14300                                        - memInfo.getSwapFreeSizeKb());
14301                                pw.print(" kB in swap (");
14302                                pw.print(memInfo.getSwapTotalSizeKb());
14303                                pw.println(" kB total swap)");
14304                    } else {
14305                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14306                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14307                                pw.println(memInfo.getSwapFreeSizeKb());
14308                    }
14309                }
14310                final int[] SINGLE_LONG_FORMAT = new int[] {
14311                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14312                };
14313                long[] longOut = new long[1];
14314                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14315                        SINGLE_LONG_FORMAT, null, longOut, null);
14316                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14317                longOut[0] = 0;
14318                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14319                        SINGLE_LONG_FORMAT, null, longOut, null);
14320                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14321                longOut[0] = 0;
14322                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14323                        SINGLE_LONG_FORMAT, null, longOut, null);
14324                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14325                longOut[0] = 0;
14326                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14327                        SINGLE_LONG_FORMAT, null, longOut, null);
14328                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14329                if (!isCompact) {
14330                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14331                        pw.print("      KSM: "); pw.print(sharing);
14332                                pw.print(" kB saved from shared ");
14333                                pw.print(shared); pw.println(" kB");
14334                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14335                                pw.print(voltile); pw.println(" kB volatile");
14336                    }
14337                    pw.print("   Tuning: ");
14338                    pw.print(ActivityManager.staticGetMemoryClass());
14339                    pw.print(" (large ");
14340                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14341                    pw.print("), oom ");
14342                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14343                    pw.print(" kB");
14344                    pw.print(", restore limit ");
14345                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14346                    pw.print(" kB");
14347                    if (ActivityManager.isLowRamDeviceStatic()) {
14348                        pw.print(" (low-ram)");
14349                    }
14350                    if (ActivityManager.isHighEndGfx()) {
14351                        pw.print(" (high-end-gfx)");
14352                    }
14353                    pw.println();
14354                } else {
14355                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14356                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14357                    pw.println(voltile);
14358                    pw.print("tuning,");
14359                    pw.print(ActivityManager.staticGetMemoryClass());
14360                    pw.print(',');
14361                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14362                    pw.print(',');
14363                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14364                    if (ActivityManager.isLowRamDeviceStatic()) {
14365                        pw.print(",low-ram");
14366                    }
14367                    if (ActivityManager.isHighEndGfx()) {
14368                        pw.print(",high-end-gfx");
14369                    }
14370                    pw.println();
14371                }
14372            }
14373        }
14374    }
14375
14376    /**
14377     * Searches array of arguments for the specified string
14378     * @param args array of argument strings
14379     * @param value value to search for
14380     * @return true if the value is contained in the array
14381     */
14382    private static boolean scanArgs(String[] args, String value) {
14383        if (args != null) {
14384            for (String arg : args) {
14385                if (value.equals(arg)) {
14386                    return true;
14387                }
14388            }
14389        }
14390        return false;
14391    }
14392
14393    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14394            ContentProviderRecord cpr, boolean always) {
14395        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14396
14397        if (!inLaunching || always) {
14398            synchronized (cpr) {
14399                cpr.launchingApp = null;
14400                cpr.notifyAll();
14401            }
14402            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14403            String names[] = cpr.info.authority.split(";");
14404            for (int j = 0; j < names.length; j++) {
14405                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14406            }
14407        }
14408
14409        for (int i=0; i<cpr.connections.size(); i++) {
14410            ContentProviderConnection conn = cpr.connections.get(i);
14411            if (conn.waiting) {
14412                // If this connection is waiting for the provider, then we don't
14413                // need to mess with its process unless we are always removing
14414                // or for some reason the provider is not currently launching.
14415                if (inLaunching && !always) {
14416                    continue;
14417                }
14418            }
14419            ProcessRecord capp = conn.client;
14420            conn.dead = true;
14421            if (conn.stableCount > 0) {
14422                if (!capp.persistent && capp.thread != null
14423                        && capp.pid != 0
14424                        && capp.pid != MY_PID) {
14425                    capp.kill("depends on provider "
14426                            + cpr.name.flattenToShortString()
14427                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14428                }
14429            } else if (capp.thread != null && conn.provider.provider != null) {
14430                try {
14431                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14432                } catch (RemoteException e) {
14433                }
14434                // In the protocol here, we don't expect the client to correctly
14435                // clean up this connection, we'll just remove it.
14436                cpr.connections.remove(i);
14437                conn.client.conProviders.remove(conn);
14438            }
14439        }
14440
14441        if (inLaunching && always) {
14442            mLaunchingProviders.remove(cpr);
14443        }
14444        return inLaunching;
14445    }
14446
14447    /**
14448     * Main code for cleaning up a process when it has gone away.  This is
14449     * called both as a result of the process dying, or directly when stopping
14450     * a process when running in single process mode.
14451     *
14452     * @return Returns true if the given process has been restarted, so the
14453     * app that was passed in must remain on the process lists.
14454     */
14455    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14456            boolean restarting, boolean allowRestart, int index) {
14457        if (index >= 0) {
14458            removeLruProcessLocked(app);
14459            ProcessList.remove(app.pid);
14460        }
14461
14462        mProcessesToGc.remove(app);
14463        mPendingPssProcesses.remove(app);
14464
14465        // Dismiss any open dialogs.
14466        if (app.crashDialog != null && !app.forceCrashReport) {
14467            app.crashDialog.dismiss();
14468            app.crashDialog = null;
14469        }
14470        if (app.anrDialog != null) {
14471            app.anrDialog.dismiss();
14472            app.anrDialog = null;
14473        }
14474        if (app.waitDialog != null) {
14475            app.waitDialog.dismiss();
14476            app.waitDialog = null;
14477        }
14478
14479        app.crashing = false;
14480        app.notResponding = false;
14481
14482        app.resetPackageList(mProcessStats);
14483        app.unlinkDeathRecipient();
14484        app.makeInactive(mProcessStats);
14485        app.waitingToKill = null;
14486        app.forcingToForeground = null;
14487        updateProcessForegroundLocked(app, false, false);
14488        app.foregroundActivities = false;
14489        app.hasShownUi = false;
14490        app.treatLikeActivity = false;
14491        app.hasAboveClient = false;
14492        app.hasClientActivities = false;
14493
14494        mServices.killServicesLocked(app, allowRestart);
14495
14496        boolean restart = false;
14497
14498        // Remove published content providers.
14499        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14500            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14501            final boolean always = app.bad || !allowRestart;
14502            if (removeDyingProviderLocked(app, cpr, always) || always) {
14503                // We left the provider in the launching list, need to
14504                // restart it.
14505                restart = true;
14506            }
14507
14508            cpr.provider = null;
14509            cpr.proc = null;
14510        }
14511        app.pubProviders.clear();
14512
14513        // Take care of any launching providers waiting for this process.
14514        if (checkAppInLaunchingProvidersLocked(app, false)) {
14515            restart = true;
14516        }
14517
14518        // Unregister from connected content providers.
14519        if (!app.conProviders.isEmpty()) {
14520            for (int i=0; i<app.conProviders.size(); i++) {
14521                ContentProviderConnection conn = app.conProviders.get(i);
14522                conn.provider.connections.remove(conn);
14523            }
14524            app.conProviders.clear();
14525        }
14526
14527        // At this point there may be remaining entries in mLaunchingProviders
14528        // where we were the only one waiting, so they are no longer of use.
14529        // Look for these and clean up if found.
14530        // XXX Commented out for now.  Trying to figure out a way to reproduce
14531        // the actual situation to identify what is actually going on.
14532        if (false) {
14533            for (int i=0; i<mLaunchingProviders.size(); i++) {
14534                ContentProviderRecord cpr = (ContentProviderRecord)
14535                        mLaunchingProviders.get(i);
14536                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14537                    synchronized (cpr) {
14538                        cpr.launchingApp = null;
14539                        cpr.notifyAll();
14540                    }
14541                }
14542            }
14543        }
14544
14545        skipCurrentReceiverLocked(app);
14546
14547        // Unregister any receivers.
14548        for (int i=app.receivers.size()-1; i>=0; i--) {
14549            removeReceiverLocked(app.receivers.valueAt(i));
14550        }
14551        app.receivers.clear();
14552
14553        // If the app is undergoing backup, tell the backup manager about it
14554        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14555            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14556                    + mBackupTarget.appInfo + " died during backup");
14557            try {
14558                IBackupManager bm = IBackupManager.Stub.asInterface(
14559                        ServiceManager.getService(Context.BACKUP_SERVICE));
14560                bm.agentDisconnected(app.info.packageName);
14561            } catch (RemoteException e) {
14562                // can't happen; backup manager is local
14563            }
14564        }
14565
14566        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14567            ProcessChangeItem item = mPendingProcessChanges.get(i);
14568            if (item.pid == app.pid) {
14569                mPendingProcessChanges.remove(i);
14570                mAvailProcessChanges.add(item);
14571            }
14572        }
14573        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14574
14575        // If the caller is restarting this app, then leave it in its
14576        // current lists and let the caller take care of it.
14577        if (restarting) {
14578            return false;
14579        }
14580
14581        if (!app.persistent || app.isolated) {
14582            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14583                    "Removing non-persistent process during cleanup: " + app);
14584            mProcessNames.remove(app.processName, app.uid);
14585            mIsolatedProcesses.remove(app.uid);
14586            if (mHeavyWeightProcess == app) {
14587                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14588                        mHeavyWeightProcess.userId, 0));
14589                mHeavyWeightProcess = null;
14590            }
14591        } else if (!app.removed) {
14592            // This app is persistent, so we need to keep its record around.
14593            // If it is not already on the pending app list, add it there
14594            // and start a new process for it.
14595            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14596                mPersistentStartingProcesses.add(app);
14597                restart = true;
14598            }
14599        }
14600        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14601                "Clean-up removing on hold: " + app);
14602        mProcessesOnHold.remove(app);
14603
14604        if (app == mHomeProcess) {
14605            mHomeProcess = null;
14606        }
14607        if (app == mPreviousProcess) {
14608            mPreviousProcess = null;
14609        }
14610
14611        if (restart && !app.isolated) {
14612            // We have components that still need to be running in the
14613            // process, so re-launch it.
14614            if (index < 0) {
14615                ProcessList.remove(app.pid);
14616            }
14617            mProcessNames.put(app.processName, app.uid, app);
14618            startProcessLocked(app, "restart", app.processName);
14619            return true;
14620        } else if (app.pid > 0 && app.pid != MY_PID) {
14621            // Goodbye!
14622            boolean removed;
14623            synchronized (mPidsSelfLocked) {
14624                mPidsSelfLocked.remove(app.pid);
14625                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14626            }
14627            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14628            if (app.isolated) {
14629                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14630            }
14631            app.setPid(0);
14632        }
14633        return false;
14634    }
14635
14636    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14637        // Look through the content providers we are waiting to have launched,
14638        // and if any run in this process then either schedule a restart of
14639        // the process or kill the client waiting for it if this process has
14640        // gone bad.
14641        int NL = mLaunchingProviders.size();
14642        boolean restart = false;
14643        for (int i=0; i<NL; i++) {
14644            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14645            if (cpr.launchingApp == app) {
14646                if (!alwaysBad && !app.bad) {
14647                    restart = true;
14648                } else {
14649                    removeDyingProviderLocked(app, cpr, true);
14650                    // cpr should have been removed from mLaunchingProviders
14651                    NL = mLaunchingProviders.size();
14652                    i--;
14653                }
14654            }
14655        }
14656        return restart;
14657    }
14658
14659    // =========================================================
14660    // SERVICES
14661    // =========================================================
14662
14663    @Override
14664    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14665            int flags) {
14666        enforceNotIsolatedCaller("getServices");
14667        synchronized (this) {
14668            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14669        }
14670    }
14671
14672    @Override
14673    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14674        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14675        synchronized (this) {
14676            return mServices.getRunningServiceControlPanelLocked(name);
14677        }
14678    }
14679
14680    @Override
14681    public ComponentName startService(IApplicationThread caller, Intent service,
14682            String resolvedType, int userId) {
14683        enforceNotIsolatedCaller("startService");
14684        // Refuse possible leaked file descriptors
14685        if (service != null && service.hasFileDescriptors() == true) {
14686            throw new IllegalArgumentException("File descriptors passed in Intent");
14687        }
14688
14689        if (DEBUG_SERVICE)
14690            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14691        synchronized(this) {
14692            final int callingPid = Binder.getCallingPid();
14693            final int callingUid = Binder.getCallingUid();
14694            final long origId = Binder.clearCallingIdentity();
14695            ComponentName res = mServices.startServiceLocked(caller, service,
14696                    resolvedType, callingPid, callingUid, userId);
14697            Binder.restoreCallingIdentity(origId);
14698            return res;
14699        }
14700    }
14701
14702    ComponentName startServiceInPackage(int uid,
14703            Intent service, String resolvedType, int userId) {
14704        synchronized(this) {
14705            if (DEBUG_SERVICE)
14706                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14707            final long origId = Binder.clearCallingIdentity();
14708            ComponentName res = mServices.startServiceLocked(null, service,
14709                    resolvedType, -1, uid, userId);
14710            Binder.restoreCallingIdentity(origId);
14711            return res;
14712        }
14713    }
14714
14715    @Override
14716    public int stopService(IApplicationThread caller, Intent service,
14717            String resolvedType, int userId) {
14718        enforceNotIsolatedCaller("stopService");
14719        // Refuse possible leaked file descriptors
14720        if (service != null && service.hasFileDescriptors() == true) {
14721            throw new IllegalArgumentException("File descriptors passed in Intent");
14722        }
14723
14724        synchronized(this) {
14725            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14726        }
14727    }
14728
14729    @Override
14730    public IBinder peekService(Intent service, String resolvedType) {
14731        enforceNotIsolatedCaller("peekService");
14732        // Refuse possible leaked file descriptors
14733        if (service != null && service.hasFileDescriptors() == true) {
14734            throw new IllegalArgumentException("File descriptors passed in Intent");
14735        }
14736        synchronized(this) {
14737            return mServices.peekServiceLocked(service, resolvedType);
14738        }
14739    }
14740
14741    @Override
14742    public boolean stopServiceToken(ComponentName className, IBinder token,
14743            int startId) {
14744        synchronized(this) {
14745            return mServices.stopServiceTokenLocked(className, token, startId);
14746        }
14747    }
14748
14749    @Override
14750    public void setServiceForeground(ComponentName className, IBinder token,
14751            int id, Notification notification, boolean removeNotification) {
14752        synchronized(this) {
14753            mServices.setServiceForegroundLocked(className, token, id, notification,
14754                    removeNotification);
14755        }
14756    }
14757
14758    @Override
14759    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14760            boolean requireFull, String name, String callerPackage) {
14761        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14762                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14763    }
14764
14765    int unsafeConvertIncomingUser(int userId) {
14766        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14767                ? mCurrentUserId : userId;
14768    }
14769
14770    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14771            int allowMode, String name, String callerPackage) {
14772        final int callingUserId = UserHandle.getUserId(callingUid);
14773        if (callingUserId == userId) {
14774            return userId;
14775        }
14776
14777        // Note that we may be accessing mCurrentUserId outside of a lock...
14778        // shouldn't be a big deal, if this is being called outside
14779        // of a locked context there is intrinsically a race with
14780        // the value the caller will receive and someone else changing it.
14781        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14782        // we will switch to the calling user if access to the current user fails.
14783        int targetUserId = unsafeConvertIncomingUser(userId);
14784
14785        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14786            final boolean allow;
14787            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14788                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14789                // If the caller has this permission, they always pass go.  And collect $200.
14790                allow = true;
14791            } else if (allowMode == ALLOW_FULL_ONLY) {
14792                // We require full access, sucks to be you.
14793                allow = false;
14794            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14795                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14796                // If the caller does not have either permission, they are always doomed.
14797                allow = false;
14798            } else if (allowMode == ALLOW_NON_FULL) {
14799                // We are blanket allowing non-full access, you lucky caller!
14800                allow = true;
14801            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14802                // We may or may not allow this depending on whether the two users are
14803                // in the same profile.
14804                synchronized (mUserProfileGroupIdsSelfLocked) {
14805                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14806                            UserInfo.NO_PROFILE_GROUP_ID);
14807                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14808                            UserInfo.NO_PROFILE_GROUP_ID);
14809                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14810                            && callingProfile == targetProfile;
14811                }
14812            } else {
14813                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14814            }
14815            if (!allow) {
14816                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14817                    // In this case, they would like to just execute as their
14818                    // owner user instead of failing.
14819                    targetUserId = callingUserId;
14820                } else {
14821                    StringBuilder builder = new StringBuilder(128);
14822                    builder.append("Permission Denial: ");
14823                    builder.append(name);
14824                    if (callerPackage != null) {
14825                        builder.append(" from ");
14826                        builder.append(callerPackage);
14827                    }
14828                    builder.append(" asks to run as user ");
14829                    builder.append(userId);
14830                    builder.append(" but is calling from user ");
14831                    builder.append(UserHandle.getUserId(callingUid));
14832                    builder.append("; this requires ");
14833                    builder.append(INTERACT_ACROSS_USERS_FULL);
14834                    if (allowMode != ALLOW_FULL_ONLY) {
14835                        builder.append(" or ");
14836                        builder.append(INTERACT_ACROSS_USERS);
14837                    }
14838                    String msg = builder.toString();
14839                    Slog.w(TAG, msg);
14840                    throw new SecurityException(msg);
14841                }
14842            }
14843        }
14844        if (!allowAll && targetUserId < 0) {
14845            throw new IllegalArgumentException(
14846                    "Call does not support special user #" + targetUserId);
14847        }
14848        // Check shell permission
14849        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14850            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14851                    targetUserId)) {
14852                throw new SecurityException("Shell does not have permission to access user "
14853                        + targetUserId + "\n " + Debug.getCallers(3));
14854            }
14855        }
14856        return targetUserId;
14857    }
14858
14859    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14860            String className, int flags) {
14861        boolean result = false;
14862        // For apps that don't have pre-defined UIDs, check for permission
14863        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14864            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14865                if (ActivityManager.checkUidPermission(
14866                        INTERACT_ACROSS_USERS,
14867                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14868                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14869                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14870                            + " requests FLAG_SINGLE_USER, but app does not hold "
14871                            + INTERACT_ACROSS_USERS;
14872                    Slog.w(TAG, msg);
14873                    throw new SecurityException(msg);
14874                }
14875                // Permission passed
14876                result = true;
14877            }
14878        } else if ("system".equals(componentProcessName)) {
14879            result = true;
14880        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14881            // Phone app and persistent apps are allowed to export singleuser providers.
14882            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14883                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14884        }
14885        if (DEBUG_MU) {
14886            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14887                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14888        }
14889        return result;
14890    }
14891
14892    /**
14893     * Checks to see if the caller is in the same app as the singleton
14894     * component, or the component is in a special app. It allows special apps
14895     * to export singleton components but prevents exporting singleton
14896     * components for regular apps.
14897     */
14898    boolean isValidSingletonCall(int callingUid, int componentUid) {
14899        int componentAppId = UserHandle.getAppId(componentUid);
14900        return UserHandle.isSameApp(callingUid, componentUid)
14901                || componentAppId == Process.SYSTEM_UID
14902                || componentAppId == Process.PHONE_UID
14903                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14904                        == PackageManager.PERMISSION_GRANTED;
14905    }
14906
14907    public int bindService(IApplicationThread caller, IBinder token,
14908            Intent service, String resolvedType,
14909            IServiceConnection connection, int flags, int userId) {
14910        enforceNotIsolatedCaller("bindService");
14911
14912        // Refuse possible leaked file descriptors
14913        if (service != null && service.hasFileDescriptors() == true) {
14914            throw new IllegalArgumentException("File descriptors passed in Intent");
14915        }
14916
14917        synchronized(this) {
14918            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14919                    connection, flags, userId);
14920        }
14921    }
14922
14923    public boolean unbindService(IServiceConnection connection) {
14924        synchronized (this) {
14925            return mServices.unbindServiceLocked(connection);
14926        }
14927    }
14928
14929    public void publishService(IBinder token, Intent intent, IBinder service) {
14930        // Refuse possible leaked file descriptors
14931        if (intent != null && intent.hasFileDescriptors() == true) {
14932            throw new IllegalArgumentException("File descriptors passed in Intent");
14933        }
14934
14935        synchronized(this) {
14936            if (!(token instanceof ServiceRecord)) {
14937                throw new IllegalArgumentException("Invalid service token");
14938            }
14939            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14940        }
14941    }
14942
14943    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14944        // Refuse possible leaked file descriptors
14945        if (intent != null && intent.hasFileDescriptors() == true) {
14946            throw new IllegalArgumentException("File descriptors passed in Intent");
14947        }
14948
14949        synchronized(this) {
14950            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14951        }
14952    }
14953
14954    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14955        synchronized(this) {
14956            if (!(token instanceof ServiceRecord)) {
14957                throw new IllegalArgumentException("Invalid service token");
14958            }
14959            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14960        }
14961    }
14962
14963    // =========================================================
14964    // BACKUP AND RESTORE
14965    // =========================================================
14966
14967    // Cause the target app to be launched if necessary and its backup agent
14968    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14969    // activity manager to announce its creation.
14970    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14971        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14972        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14973
14974        synchronized(this) {
14975            // !!! TODO: currently no check here that we're already bound
14976            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14977            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14978            synchronized (stats) {
14979                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14980            }
14981
14982            // Backup agent is now in use, its package can't be stopped.
14983            try {
14984                AppGlobals.getPackageManager().setPackageStoppedState(
14985                        app.packageName, false, UserHandle.getUserId(app.uid));
14986            } catch (RemoteException e) {
14987            } catch (IllegalArgumentException e) {
14988                Slog.w(TAG, "Failed trying to unstop package "
14989                        + app.packageName + ": " + e);
14990            }
14991
14992            BackupRecord r = new BackupRecord(ss, app, backupMode);
14993            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14994                    ? new ComponentName(app.packageName, app.backupAgentName)
14995                    : new ComponentName("android", "FullBackupAgent");
14996            // startProcessLocked() returns existing proc's record if it's already running
14997            ProcessRecord proc = startProcessLocked(app.processName, app,
14998                    false, 0, "backup", hostingName, false, false, false);
14999            if (proc == null) {
15000                Slog.e(TAG, "Unable to start backup agent process " + r);
15001                return false;
15002            }
15003
15004            r.app = proc;
15005            mBackupTarget = r;
15006            mBackupAppName = app.packageName;
15007
15008            // Try not to kill the process during backup
15009            updateOomAdjLocked(proc);
15010
15011            // If the process is already attached, schedule the creation of the backup agent now.
15012            // If it is not yet live, this will be done when it attaches to the framework.
15013            if (proc.thread != null) {
15014                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15015                try {
15016                    proc.thread.scheduleCreateBackupAgent(app,
15017                            compatibilityInfoForPackageLocked(app), backupMode);
15018                } catch (RemoteException e) {
15019                    // Will time out on the backup manager side
15020                }
15021            } else {
15022                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15023            }
15024            // Invariants: at this point, the target app process exists and the application
15025            // is either already running or in the process of coming up.  mBackupTarget and
15026            // mBackupAppName describe the app, so that when it binds back to the AM we
15027            // know that it's scheduled for a backup-agent operation.
15028        }
15029
15030        return true;
15031    }
15032
15033    @Override
15034    public void clearPendingBackup() {
15035        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15036        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15037
15038        synchronized (this) {
15039            mBackupTarget = null;
15040            mBackupAppName = null;
15041        }
15042    }
15043
15044    // A backup agent has just come up
15045    public void backupAgentCreated(String agentPackageName, IBinder agent) {
15046        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15047                + " = " + agent);
15048
15049        synchronized(this) {
15050            if (!agentPackageName.equals(mBackupAppName)) {
15051                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15052                return;
15053            }
15054        }
15055
15056        long oldIdent = Binder.clearCallingIdentity();
15057        try {
15058            IBackupManager bm = IBackupManager.Stub.asInterface(
15059                    ServiceManager.getService(Context.BACKUP_SERVICE));
15060            bm.agentConnected(agentPackageName, agent);
15061        } catch (RemoteException e) {
15062            // can't happen; the backup manager service is local
15063        } catch (Exception e) {
15064            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15065            e.printStackTrace();
15066        } finally {
15067            Binder.restoreCallingIdentity(oldIdent);
15068        }
15069    }
15070
15071    // done with this agent
15072    public void unbindBackupAgent(ApplicationInfo appInfo) {
15073        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15074        if (appInfo == null) {
15075            Slog.w(TAG, "unbind backup agent for null app");
15076            return;
15077        }
15078
15079        synchronized(this) {
15080            try {
15081                if (mBackupAppName == null) {
15082                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15083                    return;
15084                }
15085
15086                if (!mBackupAppName.equals(appInfo.packageName)) {
15087                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15088                    return;
15089                }
15090
15091                // Not backing this app up any more; reset its OOM adjustment
15092                final ProcessRecord proc = mBackupTarget.app;
15093                updateOomAdjLocked(proc);
15094
15095                // If the app crashed during backup, 'thread' will be null here
15096                if (proc.thread != null) {
15097                    try {
15098                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15099                                compatibilityInfoForPackageLocked(appInfo));
15100                    } catch (Exception e) {
15101                        Slog.e(TAG, "Exception when unbinding backup agent:");
15102                        e.printStackTrace();
15103                    }
15104                }
15105            } finally {
15106                mBackupTarget = null;
15107                mBackupAppName = null;
15108            }
15109        }
15110    }
15111    // =========================================================
15112    // BROADCASTS
15113    // =========================================================
15114
15115    private final List getStickiesLocked(String action, IntentFilter filter,
15116            List cur, int userId) {
15117        final ContentResolver resolver = mContext.getContentResolver();
15118        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15119        if (stickies == null) {
15120            return cur;
15121        }
15122        final ArrayList<Intent> list = stickies.get(action);
15123        if (list == null) {
15124            return cur;
15125        }
15126        int N = list.size();
15127        for (int i=0; i<N; i++) {
15128            Intent intent = list.get(i);
15129            if (filter.match(resolver, intent, true, TAG) >= 0) {
15130                if (cur == null) {
15131                    cur = new ArrayList<Intent>();
15132                }
15133                cur.add(intent);
15134            }
15135        }
15136        return cur;
15137    }
15138
15139    boolean isPendingBroadcastProcessLocked(int pid) {
15140        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15141                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15142    }
15143
15144    void skipPendingBroadcastLocked(int pid) {
15145            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15146            for (BroadcastQueue queue : mBroadcastQueues) {
15147                queue.skipPendingBroadcastLocked(pid);
15148            }
15149    }
15150
15151    // The app just attached; send any pending broadcasts that it should receive
15152    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15153        boolean didSomething = false;
15154        for (BroadcastQueue queue : mBroadcastQueues) {
15155            didSomething |= queue.sendPendingBroadcastsLocked(app);
15156        }
15157        return didSomething;
15158    }
15159
15160    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15161            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15162        enforceNotIsolatedCaller("registerReceiver");
15163        int callingUid;
15164        int callingPid;
15165        synchronized(this) {
15166            ProcessRecord callerApp = null;
15167            if (caller != null) {
15168                callerApp = getRecordForAppLocked(caller);
15169                if (callerApp == null) {
15170                    throw new SecurityException(
15171                            "Unable to find app for caller " + caller
15172                            + " (pid=" + Binder.getCallingPid()
15173                            + ") when registering receiver " + receiver);
15174                }
15175                if (callerApp.info.uid != Process.SYSTEM_UID &&
15176                        !callerApp.pkgList.containsKey(callerPackage) &&
15177                        !"android".equals(callerPackage)) {
15178                    throw new SecurityException("Given caller package " + callerPackage
15179                            + " is not running in process " + callerApp);
15180                }
15181                callingUid = callerApp.info.uid;
15182                callingPid = callerApp.pid;
15183            } else {
15184                callerPackage = null;
15185                callingUid = Binder.getCallingUid();
15186                callingPid = Binder.getCallingPid();
15187            }
15188
15189            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15190                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15191
15192            List allSticky = null;
15193
15194            // Look for any matching sticky broadcasts...
15195            Iterator actions = filter.actionsIterator();
15196            if (actions != null) {
15197                while (actions.hasNext()) {
15198                    String action = (String)actions.next();
15199                    allSticky = getStickiesLocked(action, filter, allSticky,
15200                            UserHandle.USER_ALL);
15201                    allSticky = getStickiesLocked(action, filter, allSticky,
15202                            UserHandle.getUserId(callingUid));
15203                }
15204            } else {
15205                allSticky = getStickiesLocked(null, filter, allSticky,
15206                        UserHandle.USER_ALL);
15207                allSticky = getStickiesLocked(null, filter, allSticky,
15208                        UserHandle.getUserId(callingUid));
15209            }
15210
15211            // The first sticky in the list is returned directly back to
15212            // the client.
15213            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15214
15215            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15216                    + ": " + sticky);
15217
15218            if (receiver == null) {
15219                return sticky;
15220            }
15221
15222            ReceiverList rl
15223                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15224            if (rl == null) {
15225                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15226                        userId, receiver);
15227                if (rl.app != null) {
15228                    rl.app.receivers.add(rl);
15229                } else {
15230                    try {
15231                        receiver.asBinder().linkToDeath(rl, 0);
15232                    } catch (RemoteException e) {
15233                        return sticky;
15234                    }
15235                    rl.linkedToDeath = true;
15236                }
15237                mRegisteredReceivers.put(receiver.asBinder(), rl);
15238            } else if (rl.uid != callingUid) {
15239                throw new IllegalArgumentException(
15240                        "Receiver requested to register for uid " + callingUid
15241                        + " was previously registered for uid " + rl.uid);
15242            } else if (rl.pid != callingPid) {
15243                throw new IllegalArgumentException(
15244                        "Receiver requested to register for pid " + callingPid
15245                        + " was previously registered for pid " + rl.pid);
15246            } else if (rl.userId != userId) {
15247                throw new IllegalArgumentException(
15248                        "Receiver requested to register for user " + userId
15249                        + " was previously registered for user " + rl.userId);
15250            }
15251            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15252                    permission, callingUid, userId);
15253            rl.add(bf);
15254            if (!bf.debugCheck()) {
15255                Slog.w(TAG, "==> For Dynamic broadast");
15256            }
15257            mReceiverResolver.addFilter(bf);
15258
15259            // Enqueue broadcasts for all existing stickies that match
15260            // this filter.
15261            if (allSticky != null) {
15262                ArrayList receivers = new ArrayList();
15263                receivers.add(bf);
15264
15265                int N = allSticky.size();
15266                for (int i=0; i<N; i++) {
15267                    Intent intent = (Intent)allSticky.get(i);
15268                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15269                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15270                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15271                            null, null, false, true, true, -1);
15272                    queue.enqueueParallelBroadcastLocked(r);
15273                    queue.scheduleBroadcastsLocked();
15274                }
15275            }
15276
15277            return sticky;
15278        }
15279    }
15280
15281    public void unregisterReceiver(IIntentReceiver receiver) {
15282        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15283
15284        final long origId = Binder.clearCallingIdentity();
15285        try {
15286            boolean doTrim = false;
15287
15288            synchronized(this) {
15289                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15290                if (rl != null) {
15291                    if (rl.curBroadcast != null) {
15292                        BroadcastRecord r = rl.curBroadcast;
15293                        final boolean doNext = finishReceiverLocked(
15294                                receiver.asBinder(), r.resultCode, r.resultData,
15295                                r.resultExtras, r.resultAbort);
15296                        if (doNext) {
15297                            doTrim = true;
15298                            r.queue.processNextBroadcast(false);
15299                        }
15300                    }
15301
15302                    if (rl.app != null) {
15303                        rl.app.receivers.remove(rl);
15304                    }
15305                    removeReceiverLocked(rl);
15306                    if (rl.linkedToDeath) {
15307                        rl.linkedToDeath = false;
15308                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15309                    }
15310                }
15311            }
15312
15313            // If we actually concluded any broadcasts, we might now be able
15314            // to trim the recipients' apps from our working set
15315            if (doTrim) {
15316                trimApplications();
15317                return;
15318            }
15319
15320        } finally {
15321            Binder.restoreCallingIdentity(origId);
15322        }
15323    }
15324
15325    void removeReceiverLocked(ReceiverList rl) {
15326        mRegisteredReceivers.remove(rl.receiver.asBinder());
15327        int N = rl.size();
15328        for (int i=0; i<N; i++) {
15329            mReceiverResolver.removeFilter(rl.get(i));
15330        }
15331    }
15332
15333    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15334        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15335            ProcessRecord r = mLruProcesses.get(i);
15336            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15337                try {
15338                    r.thread.dispatchPackageBroadcast(cmd, packages);
15339                } catch (RemoteException ex) {
15340                }
15341            }
15342        }
15343    }
15344
15345    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15346            int callingUid, int[] users) {
15347        List<ResolveInfo> receivers = null;
15348        try {
15349            HashSet<ComponentName> singleUserReceivers = null;
15350            boolean scannedFirstReceivers = false;
15351            for (int user : users) {
15352                // Skip users that have Shell restrictions
15353                if (callingUid == Process.SHELL_UID
15354                        && getUserManagerLocked().hasUserRestriction(
15355                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15356                    continue;
15357                }
15358                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15359                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15360                if (user != 0 && newReceivers != null) {
15361                    // If this is not the primary user, we need to check for
15362                    // any receivers that should be filtered out.
15363                    for (int i=0; i<newReceivers.size(); i++) {
15364                        ResolveInfo ri = newReceivers.get(i);
15365                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15366                            newReceivers.remove(i);
15367                            i--;
15368                        }
15369                    }
15370                }
15371                if (newReceivers != null && newReceivers.size() == 0) {
15372                    newReceivers = null;
15373                }
15374                if (receivers == null) {
15375                    receivers = newReceivers;
15376                } else if (newReceivers != null) {
15377                    // We need to concatenate the additional receivers
15378                    // found with what we have do far.  This would be easy,
15379                    // but we also need to de-dup any receivers that are
15380                    // singleUser.
15381                    if (!scannedFirstReceivers) {
15382                        // Collect any single user receivers we had already retrieved.
15383                        scannedFirstReceivers = true;
15384                        for (int i=0; i<receivers.size(); i++) {
15385                            ResolveInfo ri = receivers.get(i);
15386                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15387                                ComponentName cn = new ComponentName(
15388                                        ri.activityInfo.packageName, ri.activityInfo.name);
15389                                if (singleUserReceivers == null) {
15390                                    singleUserReceivers = new HashSet<ComponentName>();
15391                                }
15392                                singleUserReceivers.add(cn);
15393                            }
15394                        }
15395                    }
15396                    // Add the new results to the existing results, tracking
15397                    // and de-dupping single user receivers.
15398                    for (int i=0; i<newReceivers.size(); i++) {
15399                        ResolveInfo ri = newReceivers.get(i);
15400                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15401                            ComponentName cn = new ComponentName(
15402                                    ri.activityInfo.packageName, ri.activityInfo.name);
15403                            if (singleUserReceivers == null) {
15404                                singleUserReceivers = new HashSet<ComponentName>();
15405                            }
15406                            if (!singleUserReceivers.contains(cn)) {
15407                                singleUserReceivers.add(cn);
15408                                receivers.add(ri);
15409                            }
15410                        } else {
15411                            receivers.add(ri);
15412                        }
15413                    }
15414                }
15415            }
15416        } catch (RemoteException ex) {
15417            // pm is in same process, this will never happen.
15418        }
15419        return receivers;
15420    }
15421
15422    private final int broadcastIntentLocked(ProcessRecord callerApp,
15423            String callerPackage, Intent intent, String resolvedType,
15424            IIntentReceiver resultTo, int resultCode, String resultData,
15425            Bundle map, String requiredPermission, int appOp,
15426            boolean ordered, boolean sticky, int callingPid, int callingUid,
15427            int userId) {
15428        intent = new Intent(intent);
15429
15430        // By default broadcasts do not go to stopped apps.
15431        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15432
15433        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15434            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15435            + " ordered=" + ordered + " userid=" + userId);
15436        if ((resultTo != null) && !ordered) {
15437            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15438        }
15439
15440        userId = handleIncomingUser(callingPid, callingUid, userId,
15441                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15442
15443        // Make sure that the user who is receiving this broadcast is started.
15444        // If not, we will just skip it.
15445
15446        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15447            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15448                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15449                Slog.w(TAG, "Skipping broadcast of " + intent
15450                        + ": user " + userId + " is stopped");
15451                return ActivityManager.BROADCAST_SUCCESS;
15452            }
15453        }
15454
15455        /*
15456         * Prevent non-system code (defined here to be non-persistent
15457         * processes) from sending protected broadcasts.
15458         */
15459        int callingAppId = UserHandle.getAppId(callingUid);
15460        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15461            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15462            || callingAppId == Process.NFC_UID || callingUid == 0) {
15463            // Always okay.
15464        } else if (callerApp == null || !callerApp.persistent) {
15465            try {
15466                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15467                        intent.getAction())) {
15468                    String msg = "Permission Denial: not allowed to send broadcast "
15469                            + intent.getAction() + " from pid="
15470                            + callingPid + ", uid=" + callingUid;
15471                    Slog.w(TAG, msg);
15472                    throw new SecurityException(msg);
15473                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15474                    // Special case for compatibility: we don't want apps to send this,
15475                    // but historically it has not been protected and apps may be using it
15476                    // to poke their own app widget.  So, instead of making it protected,
15477                    // just limit it to the caller.
15478                    if (callerApp == null) {
15479                        String msg = "Permission Denial: not allowed to send broadcast "
15480                                + intent.getAction() + " from unknown caller.";
15481                        Slog.w(TAG, msg);
15482                        throw new SecurityException(msg);
15483                    } else if (intent.getComponent() != null) {
15484                        // They are good enough to send to an explicit component...  verify
15485                        // it is being sent to the calling app.
15486                        if (!intent.getComponent().getPackageName().equals(
15487                                callerApp.info.packageName)) {
15488                            String msg = "Permission Denial: not allowed to send broadcast "
15489                                    + intent.getAction() + " to "
15490                                    + intent.getComponent().getPackageName() + " from "
15491                                    + callerApp.info.packageName;
15492                            Slog.w(TAG, msg);
15493                            throw new SecurityException(msg);
15494                        }
15495                    } else {
15496                        // Limit broadcast to their own package.
15497                        intent.setPackage(callerApp.info.packageName);
15498                    }
15499                }
15500            } catch (RemoteException e) {
15501                Slog.w(TAG, "Remote exception", e);
15502                return ActivityManager.BROADCAST_SUCCESS;
15503            }
15504        }
15505
15506        // Handle special intents: if this broadcast is from the package
15507        // manager about a package being removed, we need to remove all of
15508        // its activities from the history stack.
15509        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15510                intent.getAction());
15511        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15512                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15513                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15514                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15515                || uidRemoved) {
15516            if (checkComponentPermission(
15517                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15518                    callingPid, callingUid, -1, true)
15519                    == PackageManager.PERMISSION_GRANTED) {
15520                if (uidRemoved) {
15521                    final Bundle intentExtras = intent.getExtras();
15522                    final int uid = intentExtras != null
15523                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15524                    if (uid >= 0) {
15525                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15526                        synchronized (bs) {
15527                            bs.removeUidStatsLocked(uid);
15528                        }
15529                        mAppOpsService.uidRemoved(uid);
15530                    }
15531                } else {
15532                    // If resources are unavailable just force stop all
15533                    // those packages and flush the attribute cache as well.
15534                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15535                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15536                        if (list != null && (list.length > 0)) {
15537                            for (String pkg : list) {
15538                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15539                                        "storage unmount");
15540                            }
15541                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15542                            sendPackageBroadcastLocked(
15543                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15544                        }
15545                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15546                            intent.getAction())) {
15547                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15548                    } else {
15549                        Uri data = intent.getData();
15550                        String ssp;
15551                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15552                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15553                                    intent.getAction());
15554                            boolean fullUninstall = removed &&
15555                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15556                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15557                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15558                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15559                                        false, fullUninstall, userId,
15560                                        removed ? "pkg removed" : "pkg changed");
15561                            }
15562                            if (removed) {
15563                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15564                                        new String[] {ssp}, userId);
15565                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15566                                    mAppOpsService.packageRemoved(
15567                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15568
15569                                    // Remove all permissions granted from/to this package
15570                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15571                                }
15572                            }
15573                        }
15574                    }
15575                }
15576            } else {
15577                String msg = "Permission Denial: " + intent.getAction()
15578                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15579                        + ", uid=" + callingUid + ")"
15580                        + " requires "
15581                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15582                Slog.w(TAG, msg);
15583                throw new SecurityException(msg);
15584            }
15585
15586        // Special case for adding a package: by default turn on compatibility
15587        // mode.
15588        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15589            Uri data = intent.getData();
15590            String ssp;
15591            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15592                mCompatModePackages.handlePackageAddedLocked(ssp,
15593                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15594            }
15595        }
15596
15597        /*
15598         * If this is the time zone changed action, queue up a message that will reset the timezone
15599         * of all currently running processes. This message will get queued up before the broadcast
15600         * happens.
15601         */
15602        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15603            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15604        }
15605
15606        /*
15607         * If the user set the time, let all running processes know.
15608         */
15609        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15610            final int is24Hour = intent.getBooleanExtra(
15611                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15612            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15613            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15614            synchronized (stats) {
15615                stats.noteCurrentTimeChangedLocked();
15616            }
15617        }
15618
15619        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15620            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15621        }
15622
15623        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15624            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15625            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15626        }
15627
15628        // Add to the sticky list if requested.
15629        if (sticky) {
15630            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15631                    callingPid, callingUid)
15632                    != PackageManager.PERMISSION_GRANTED) {
15633                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15634                        + callingPid + ", uid=" + callingUid
15635                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15636                Slog.w(TAG, msg);
15637                throw new SecurityException(msg);
15638            }
15639            if (requiredPermission != null) {
15640                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15641                        + " and enforce permission " + requiredPermission);
15642                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15643            }
15644            if (intent.getComponent() != null) {
15645                throw new SecurityException(
15646                        "Sticky broadcasts can't target a specific component");
15647            }
15648            // We use userId directly here, since the "all" target is maintained
15649            // as a separate set of sticky broadcasts.
15650            if (userId != UserHandle.USER_ALL) {
15651                // But first, if this is not a broadcast to all users, then
15652                // make sure it doesn't conflict with an existing broadcast to
15653                // all users.
15654                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15655                        UserHandle.USER_ALL);
15656                if (stickies != null) {
15657                    ArrayList<Intent> list = stickies.get(intent.getAction());
15658                    if (list != null) {
15659                        int N = list.size();
15660                        int i;
15661                        for (i=0; i<N; i++) {
15662                            if (intent.filterEquals(list.get(i))) {
15663                                throw new IllegalArgumentException(
15664                                        "Sticky broadcast " + intent + " for user "
15665                                        + userId + " conflicts with existing global broadcast");
15666                            }
15667                        }
15668                    }
15669                }
15670            }
15671            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15672            if (stickies == null) {
15673                stickies = new ArrayMap<String, ArrayList<Intent>>();
15674                mStickyBroadcasts.put(userId, stickies);
15675            }
15676            ArrayList<Intent> list = stickies.get(intent.getAction());
15677            if (list == null) {
15678                list = new ArrayList<Intent>();
15679                stickies.put(intent.getAction(), list);
15680            }
15681            int N = list.size();
15682            int i;
15683            for (i=0; i<N; i++) {
15684                if (intent.filterEquals(list.get(i))) {
15685                    // This sticky already exists, replace it.
15686                    list.set(i, new Intent(intent));
15687                    break;
15688                }
15689            }
15690            if (i >= N) {
15691                list.add(new Intent(intent));
15692            }
15693        }
15694
15695        int[] users;
15696        if (userId == UserHandle.USER_ALL) {
15697            // Caller wants broadcast to go to all started users.
15698            users = mStartedUserArray;
15699        } else {
15700            // Caller wants broadcast to go to one specific user.
15701            users = new int[] {userId};
15702        }
15703
15704        // Figure out who all will receive this broadcast.
15705        List receivers = null;
15706        List<BroadcastFilter> registeredReceivers = null;
15707        // Need to resolve the intent to interested receivers...
15708        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15709                 == 0) {
15710            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15711        }
15712        if (intent.getComponent() == null) {
15713            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15714                // Query one target user at a time, excluding shell-restricted users
15715                UserManagerService ums = getUserManagerLocked();
15716                for (int i = 0; i < users.length; i++) {
15717                    if (ums.hasUserRestriction(
15718                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15719                        continue;
15720                    }
15721                    List<BroadcastFilter> registeredReceiversForUser =
15722                            mReceiverResolver.queryIntent(intent,
15723                                    resolvedType, false, users[i]);
15724                    if (registeredReceivers == null) {
15725                        registeredReceivers = registeredReceiversForUser;
15726                    } else if (registeredReceiversForUser != null) {
15727                        registeredReceivers.addAll(registeredReceiversForUser);
15728                    }
15729                }
15730            } else {
15731                registeredReceivers = mReceiverResolver.queryIntent(intent,
15732                        resolvedType, false, userId);
15733            }
15734        }
15735
15736        final boolean replacePending =
15737                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15738
15739        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15740                + " replacePending=" + replacePending);
15741
15742        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15743        if (!ordered && NR > 0) {
15744            // If we are not serializing this broadcast, then send the
15745            // registered receivers separately so they don't wait for the
15746            // components to be launched.
15747            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15748            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15749                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15750                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15751                    ordered, sticky, false, userId);
15752            if (DEBUG_BROADCAST) Slog.v(
15753                    TAG, "Enqueueing parallel broadcast " + r);
15754            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15755            if (!replaced) {
15756                queue.enqueueParallelBroadcastLocked(r);
15757                queue.scheduleBroadcastsLocked();
15758            }
15759            registeredReceivers = null;
15760            NR = 0;
15761        }
15762
15763        // Merge into one list.
15764        int ir = 0;
15765        if (receivers != null) {
15766            // A special case for PACKAGE_ADDED: do not allow the package
15767            // being added to see this broadcast.  This prevents them from
15768            // using this as a back door to get run as soon as they are
15769            // installed.  Maybe in the future we want to have a special install
15770            // broadcast or such for apps, but we'd like to deliberately make
15771            // this decision.
15772            String skipPackages[] = null;
15773            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15774                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15775                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15776                Uri data = intent.getData();
15777                if (data != null) {
15778                    String pkgName = data.getSchemeSpecificPart();
15779                    if (pkgName != null) {
15780                        skipPackages = new String[] { pkgName };
15781                    }
15782                }
15783            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15784                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15785            }
15786            if (skipPackages != null && (skipPackages.length > 0)) {
15787                for (String skipPackage : skipPackages) {
15788                    if (skipPackage != null) {
15789                        int NT = receivers.size();
15790                        for (int it=0; it<NT; it++) {
15791                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15792                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15793                                receivers.remove(it);
15794                                it--;
15795                                NT--;
15796                            }
15797                        }
15798                    }
15799                }
15800            }
15801
15802            int NT = receivers != null ? receivers.size() : 0;
15803            int it = 0;
15804            ResolveInfo curt = null;
15805            BroadcastFilter curr = null;
15806            while (it < NT && ir < NR) {
15807                if (curt == null) {
15808                    curt = (ResolveInfo)receivers.get(it);
15809                }
15810                if (curr == null) {
15811                    curr = registeredReceivers.get(ir);
15812                }
15813                if (curr.getPriority() >= curt.priority) {
15814                    // Insert this broadcast record into the final list.
15815                    receivers.add(it, curr);
15816                    ir++;
15817                    curr = null;
15818                    it++;
15819                    NT++;
15820                } else {
15821                    // Skip to the next ResolveInfo in the final list.
15822                    it++;
15823                    curt = null;
15824                }
15825            }
15826        }
15827        while (ir < NR) {
15828            if (receivers == null) {
15829                receivers = new ArrayList();
15830            }
15831            receivers.add(registeredReceivers.get(ir));
15832            ir++;
15833        }
15834
15835        if ((receivers != null && receivers.size() > 0)
15836                || resultTo != null) {
15837            BroadcastQueue queue = broadcastQueueForIntent(intent);
15838            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15839                    callerPackage, callingPid, callingUid, resolvedType,
15840                    requiredPermission, appOp, receivers, resultTo, resultCode,
15841                    resultData, map, ordered, sticky, false, userId);
15842            if (DEBUG_BROADCAST) Slog.v(
15843                    TAG, "Enqueueing ordered broadcast " + r
15844                    + ": prev had " + queue.mOrderedBroadcasts.size());
15845            if (DEBUG_BROADCAST) {
15846                int seq = r.intent.getIntExtra("seq", -1);
15847                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15848            }
15849            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15850            if (!replaced) {
15851                queue.enqueueOrderedBroadcastLocked(r);
15852                queue.scheduleBroadcastsLocked();
15853            }
15854        }
15855
15856        return ActivityManager.BROADCAST_SUCCESS;
15857    }
15858
15859    final Intent verifyBroadcastLocked(Intent intent) {
15860        // Refuse possible leaked file descriptors
15861        if (intent != null && intent.hasFileDescriptors() == true) {
15862            throw new IllegalArgumentException("File descriptors passed in Intent");
15863        }
15864
15865        int flags = intent.getFlags();
15866
15867        if (!mProcessesReady) {
15868            // if the caller really truly claims to know what they're doing, go
15869            // ahead and allow the broadcast without launching any receivers
15870            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15871                intent = new Intent(intent);
15872                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15873            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15874                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15875                        + " before boot completion");
15876                throw new IllegalStateException("Cannot broadcast before boot completed");
15877            }
15878        }
15879
15880        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15881            throw new IllegalArgumentException(
15882                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15883        }
15884
15885        return intent;
15886    }
15887
15888    public final int broadcastIntent(IApplicationThread caller,
15889            Intent intent, String resolvedType, IIntentReceiver resultTo,
15890            int resultCode, String resultData, Bundle map,
15891            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15892        enforceNotIsolatedCaller("broadcastIntent");
15893        synchronized(this) {
15894            intent = verifyBroadcastLocked(intent);
15895
15896            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15897            final int callingPid = Binder.getCallingPid();
15898            final int callingUid = Binder.getCallingUid();
15899            final long origId = Binder.clearCallingIdentity();
15900            int res = broadcastIntentLocked(callerApp,
15901                    callerApp != null ? callerApp.info.packageName : null,
15902                    intent, resolvedType, resultTo,
15903                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15904                    callingPid, callingUid, userId);
15905            Binder.restoreCallingIdentity(origId);
15906            return res;
15907        }
15908    }
15909
15910    int broadcastIntentInPackage(String packageName, int uid,
15911            Intent intent, String resolvedType, IIntentReceiver resultTo,
15912            int resultCode, String resultData, Bundle map,
15913            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15914        synchronized(this) {
15915            intent = verifyBroadcastLocked(intent);
15916
15917            final long origId = Binder.clearCallingIdentity();
15918            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15919                    resultTo, resultCode, resultData, map, requiredPermission,
15920                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15921            Binder.restoreCallingIdentity(origId);
15922            return res;
15923        }
15924    }
15925
15926    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15927        // Refuse possible leaked file descriptors
15928        if (intent != null && intent.hasFileDescriptors() == true) {
15929            throw new IllegalArgumentException("File descriptors passed in Intent");
15930        }
15931
15932        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15933                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15934
15935        synchronized(this) {
15936            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15937                    != PackageManager.PERMISSION_GRANTED) {
15938                String msg = "Permission Denial: unbroadcastIntent() from pid="
15939                        + Binder.getCallingPid()
15940                        + ", uid=" + Binder.getCallingUid()
15941                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15942                Slog.w(TAG, msg);
15943                throw new SecurityException(msg);
15944            }
15945            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15946            if (stickies != null) {
15947                ArrayList<Intent> list = stickies.get(intent.getAction());
15948                if (list != null) {
15949                    int N = list.size();
15950                    int i;
15951                    for (i=0; i<N; i++) {
15952                        if (intent.filterEquals(list.get(i))) {
15953                            list.remove(i);
15954                            break;
15955                        }
15956                    }
15957                    if (list.size() <= 0) {
15958                        stickies.remove(intent.getAction());
15959                    }
15960                }
15961                if (stickies.size() <= 0) {
15962                    mStickyBroadcasts.remove(userId);
15963                }
15964            }
15965        }
15966    }
15967
15968    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15969            String resultData, Bundle resultExtras, boolean resultAbort) {
15970        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15971        if (r == null) {
15972            Slog.w(TAG, "finishReceiver called but not found on queue");
15973            return false;
15974        }
15975
15976        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15977    }
15978
15979    void backgroundServicesFinishedLocked(int userId) {
15980        for (BroadcastQueue queue : mBroadcastQueues) {
15981            queue.backgroundServicesFinishedLocked(userId);
15982        }
15983    }
15984
15985    public void finishReceiver(IBinder who, int resultCode, String resultData,
15986            Bundle resultExtras, boolean resultAbort) {
15987        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15988
15989        // Refuse possible leaked file descriptors
15990        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15991            throw new IllegalArgumentException("File descriptors passed in Bundle");
15992        }
15993
15994        final long origId = Binder.clearCallingIdentity();
15995        try {
15996            boolean doNext = false;
15997            BroadcastRecord r;
15998
15999            synchronized(this) {
16000                r = broadcastRecordForReceiverLocked(who);
16001                if (r != null) {
16002                    doNext = r.queue.finishReceiverLocked(r, resultCode,
16003                        resultData, resultExtras, resultAbort, true);
16004                }
16005            }
16006
16007            if (doNext) {
16008                r.queue.processNextBroadcast(false);
16009            }
16010            trimApplications();
16011        } finally {
16012            Binder.restoreCallingIdentity(origId);
16013        }
16014    }
16015
16016    // =========================================================
16017    // INSTRUMENTATION
16018    // =========================================================
16019
16020    public boolean startInstrumentation(ComponentName className,
16021            String profileFile, int flags, Bundle arguments,
16022            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16023            int userId, String abiOverride) {
16024        enforceNotIsolatedCaller("startInstrumentation");
16025        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16026                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16027        // Refuse possible leaked file descriptors
16028        if (arguments != null && arguments.hasFileDescriptors()) {
16029            throw new IllegalArgumentException("File descriptors passed in Bundle");
16030        }
16031
16032        synchronized(this) {
16033            InstrumentationInfo ii = null;
16034            ApplicationInfo ai = null;
16035            try {
16036                ii = mContext.getPackageManager().getInstrumentationInfo(
16037                    className, STOCK_PM_FLAGS);
16038                ai = AppGlobals.getPackageManager().getApplicationInfo(
16039                        ii.targetPackage, STOCK_PM_FLAGS, userId);
16040            } catch (PackageManager.NameNotFoundException e) {
16041            } catch (RemoteException e) {
16042            }
16043            if (ii == null) {
16044                reportStartInstrumentationFailure(watcher, className,
16045                        "Unable to find instrumentation info for: " + className);
16046                return false;
16047            }
16048            if (ai == null) {
16049                reportStartInstrumentationFailure(watcher, className,
16050                        "Unable to find instrumentation target package: " + ii.targetPackage);
16051                return false;
16052            }
16053
16054            int match = mContext.getPackageManager().checkSignatures(
16055                    ii.targetPackage, ii.packageName);
16056            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16057                String msg = "Permission Denial: starting instrumentation "
16058                        + className + " from pid="
16059                        + Binder.getCallingPid()
16060                        + ", uid=" + Binder.getCallingPid()
16061                        + " not allowed because package " + ii.packageName
16062                        + " does not have a signature matching the target "
16063                        + ii.targetPackage;
16064                reportStartInstrumentationFailure(watcher, className, msg);
16065                throw new SecurityException(msg);
16066            }
16067
16068            final long origId = Binder.clearCallingIdentity();
16069            // Instrumentation can kill and relaunch even persistent processes
16070            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16071                    "start instr");
16072            ProcessRecord app = addAppLocked(ai, false, abiOverride);
16073            app.instrumentationClass = className;
16074            app.instrumentationInfo = ai;
16075            app.instrumentationProfileFile = profileFile;
16076            app.instrumentationArguments = arguments;
16077            app.instrumentationWatcher = watcher;
16078            app.instrumentationUiAutomationConnection = uiAutomationConnection;
16079            app.instrumentationResultClass = className;
16080            Binder.restoreCallingIdentity(origId);
16081        }
16082
16083        return true;
16084    }
16085
16086    /**
16087     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16088     * error to the logs, but if somebody is watching, send the report there too.  This enables
16089     * the "am" command to report errors with more information.
16090     *
16091     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16092     * @param cn The component name of the instrumentation.
16093     * @param report The error report.
16094     */
16095    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16096            ComponentName cn, String report) {
16097        Slog.w(TAG, report);
16098        try {
16099            if (watcher != null) {
16100                Bundle results = new Bundle();
16101                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16102                results.putString("Error", report);
16103                watcher.instrumentationStatus(cn, -1, results);
16104            }
16105        } catch (RemoteException e) {
16106            Slog.w(TAG, e);
16107        }
16108    }
16109
16110    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16111        if (app.instrumentationWatcher != null) {
16112            try {
16113                // NOTE:  IInstrumentationWatcher *must* be oneway here
16114                app.instrumentationWatcher.instrumentationFinished(
16115                    app.instrumentationClass,
16116                    resultCode,
16117                    results);
16118            } catch (RemoteException e) {
16119            }
16120        }
16121        if (app.instrumentationUiAutomationConnection != null) {
16122            try {
16123                app.instrumentationUiAutomationConnection.shutdown();
16124            } catch (RemoteException re) {
16125                /* ignore */
16126            }
16127            // Only a UiAutomation can set this flag and now that
16128            // it is finished we make sure it is reset to its default.
16129            mUserIsMonkey = false;
16130        }
16131        app.instrumentationWatcher = null;
16132        app.instrumentationUiAutomationConnection = null;
16133        app.instrumentationClass = null;
16134        app.instrumentationInfo = null;
16135        app.instrumentationProfileFile = null;
16136        app.instrumentationArguments = null;
16137
16138        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16139                "finished inst");
16140    }
16141
16142    public void finishInstrumentation(IApplicationThread target,
16143            int resultCode, Bundle results) {
16144        int userId = UserHandle.getCallingUserId();
16145        // Refuse possible leaked file descriptors
16146        if (results != null && results.hasFileDescriptors()) {
16147            throw new IllegalArgumentException("File descriptors passed in Intent");
16148        }
16149
16150        synchronized(this) {
16151            ProcessRecord app = getRecordForAppLocked(target);
16152            if (app == null) {
16153                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16154                return;
16155            }
16156            final long origId = Binder.clearCallingIdentity();
16157            finishInstrumentationLocked(app, resultCode, results);
16158            Binder.restoreCallingIdentity(origId);
16159        }
16160    }
16161
16162    // =========================================================
16163    // CONFIGURATION
16164    // =========================================================
16165
16166    public ConfigurationInfo getDeviceConfigurationInfo() {
16167        ConfigurationInfo config = new ConfigurationInfo();
16168        synchronized (this) {
16169            config.reqTouchScreen = mConfiguration.touchscreen;
16170            config.reqKeyboardType = mConfiguration.keyboard;
16171            config.reqNavigation = mConfiguration.navigation;
16172            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16173                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16174                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16175            }
16176            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16177                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16178                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16179            }
16180            config.reqGlEsVersion = GL_ES_VERSION;
16181        }
16182        return config;
16183    }
16184
16185    ActivityStack getFocusedStack() {
16186        return mStackSupervisor.getFocusedStack();
16187    }
16188
16189    public Configuration getConfiguration() {
16190        Configuration ci;
16191        synchronized(this) {
16192            ci = new Configuration(mConfiguration);
16193        }
16194        return ci;
16195    }
16196
16197    public void updatePersistentConfiguration(Configuration values) {
16198        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16199                "updateConfiguration()");
16200        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16201                "updateConfiguration()");
16202        if (values == null) {
16203            throw new NullPointerException("Configuration must not be null");
16204        }
16205
16206        synchronized(this) {
16207            final long origId = Binder.clearCallingIdentity();
16208            updateConfigurationLocked(values, null, true, false);
16209            Binder.restoreCallingIdentity(origId);
16210        }
16211    }
16212
16213    public void updateConfiguration(Configuration values) {
16214        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16215                "updateConfiguration()");
16216
16217        synchronized(this) {
16218            if (values == null && mWindowManager != null) {
16219                // sentinel: fetch the current configuration from the window manager
16220                values = mWindowManager.computeNewConfiguration();
16221            }
16222
16223            if (mWindowManager != null) {
16224                mProcessList.applyDisplaySize(mWindowManager);
16225            }
16226
16227            final long origId = Binder.clearCallingIdentity();
16228            if (values != null) {
16229                Settings.System.clearConfiguration(values);
16230            }
16231            updateConfigurationLocked(values, null, false, false);
16232            Binder.restoreCallingIdentity(origId);
16233        }
16234    }
16235
16236    /**
16237     * Do either or both things: (1) change the current configuration, and (2)
16238     * make sure the given activity is running with the (now) current
16239     * configuration.  Returns true if the activity has been left running, or
16240     * false if <var>starting</var> is being destroyed to match the new
16241     * configuration.
16242     * @param persistent TODO
16243     */
16244    boolean updateConfigurationLocked(Configuration values,
16245            ActivityRecord starting, boolean persistent, boolean initLocale) {
16246        int changes = 0;
16247
16248        if (values != null) {
16249            Configuration newConfig = new Configuration(mConfiguration);
16250            changes = newConfig.updateFrom(values);
16251            if (changes != 0) {
16252                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16253                    Slog.i(TAG, "Updating configuration to: " + values);
16254                }
16255
16256                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16257
16258                if (values.locale != null && !initLocale) {
16259                    saveLocaleLocked(values.locale,
16260                                     !values.locale.equals(mConfiguration.locale),
16261                                     values.userSetLocale);
16262                }
16263
16264                mConfigurationSeq++;
16265                if (mConfigurationSeq <= 0) {
16266                    mConfigurationSeq = 1;
16267                }
16268                newConfig.seq = mConfigurationSeq;
16269                mConfiguration = newConfig;
16270                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16271                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16272                //mUsageStatsService.noteStartConfig(newConfig);
16273
16274                final Configuration configCopy = new Configuration(mConfiguration);
16275
16276                // TODO: If our config changes, should we auto dismiss any currently
16277                // showing dialogs?
16278                mShowDialogs = shouldShowDialogs(newConfig);
16279
16280                AttributeCache ac = AttributeCache.instance();
16281                if (ac != null) {
16282                    ac.updateConfiguration(configCopy);
16283                }
16284
16285                // Make sure all resources in our process are updated
16286                // right now, so that anyone who is going to retrieve
16287                // resource values after we return will be sure to get
16288                // the new ones.  This is especially important during
16289                // boot, where the first config change needs to guarantee
16290                // all resources have that config before following boot
16291                // code is executed.
16292                mSystemThread.applyConfigurationToResources(configCopy);
16293
16294                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16295                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16296                    msg.obj = new Configuration(configCopy);
16297                    mHandler.sendMessage(msg);
16298                }
16299
16300                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16301                    ProcessRecord app = mLruProcesses.get(i);
16302                    try {
16303                        if (app.thread != null) {
16304                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16305                                    + app.processName + " new config " + mConfiguration);
16306                            app.thread.scheduleConfigurationChanged(configCopy);
16307                        }
16308                    } catch (Exception e) {
16309                    }
16310                }
16311                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16312                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16313                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16314                        | Intent.FLAG_RECEIVER_FOREGROUND);
16315                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16316                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16317                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16318                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16319                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16320                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16321                    broadcastIntentLocked(null, null, intent,
16322                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16323                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16324                }
16325            }
16326        }
16327
16328        boolean kept = true;
16329        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16330        // mainStack is null during startup.
16331        if (mainStack != null) {
16332            if (changes != 0 && starting == null) {
16333                // If the configuration changed, and the caller is not already
16334                // in the process of starting an activity, then find the top
16335                // activity to check if its configuration needs to change.
16336                starting = mainStack.topRunningActivityLocked(null);
16337            }
16338
16339            if (starting != null) {
16340                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16341                // And we need to make sure at this point that all other activities
16342                // are made visible with the correct configuration.
16343                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16344            }
16345        }
16346
16347        if (values != null && mWindowManager != null) {
16348            mWindowManager.setNewConfiguration(mConfiguration);
16349        }
16350
16351        return kept;
16352    }
16353
16354    /**
16355     * Decide based on the configuration whether we should shouw the ANR,
16356     * crash, etc dialogs.  The idea is that if there is no affordnace to
16357     * press the on-screen buttons, we shouldn't show the dialog.
16358     *
16359     * A thought: SystemUI might also want to get told about this, the Power
16360     * dialog / global actions also might want different behaviors.
16361     */
16362    private static final boolean shouldShowDialogs(Configuration config) {
16363        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16364                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16365    }
16366
16367    /**
16368     * Save the locale.  You must be inside a synchronized (this) block.
16369     */
16370    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16371        if(isDiff) {
16372            SystemProperties.set("user.language", l.getLanguage());
16373            SystemProperties.set("user.region", l.getCountry());
16374        }
16375
16376        if(isPersist) {
16377            SystemProperties.set("persist.sys.language", l.getLanguage());
16378            SystemProperties.set("persist.sys.country", l.getCountry());
16379            SystemProperties.set("persist.sys.localevar", l.getVariant());
16380
16381            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16382        }
16383    }
16384
16385    @Override
16386    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16387        synchronized (this) {
16388            ActivityRecord srec = ActivityRecord.forToken(token);
16389            if (srec.task != null && srec.task.stack != null) {
16390                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16391            }
16392        }
16393        return false;
16394    }
16395
16396    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16397            Intent resultData) {
16398
16399        synchronized (this) {
16400            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16401            if (stack != null) {
16402                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16403            }
16404            return false;
16405        }
16406    }
16407
16408    public int getLaunchedFromUid(IBinder activityToken) {
16409        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16410        if (srec == null) {
16411            return -1;
16412        }
16413        return srec.launchedFromUid;
16414    }
16415
16416    public String getLaunchedFromPackage(IBinder activityToken) {
16417        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16418        if (srec == null) {
16419            return null;
16420        }
16421        return srec.launchedFromPackage;
16422    }
16423
16424    // =========================================================
16425    // LIFETIME MANAGEMENT
16426    // =========================================================
16427
16428    // Returns which broadcast queue the app is the current [or imminent] receiver
16429    // on, or 'null' if the app is not an active broadcast recipient.
16430    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16431        BroadcastRecord r = app.curReceiver;
16432        if (r != null) {
16433            return r.queue;
16434        }
16435
16436        // It's not the current receiver, but it might be starting up to become one
16437        synchronized (this) {
16438            for (BroadcastQueue queue : mBroadcastQueues) {
16439                r = queue.mPendingBroadcast;
16440                if (r != null && r.curApp == app) {
16441                    // found it; report which queue it's in
16442                    return queue;
16443                }
16444            }
16445        }
16446
16447        return null;
16448    }
16449
16450    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16451            boolean doingAll, long now) {
16452        if (mAdjSeq == app.adjSeq) {
16453            // This adjustment has already been computed.
16454            return app.curRawAdj;
16455        }
16456
16457        if (app.thread == null) {
16458            app.adjSeq = mAdjSeq;
16459            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16460            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16461            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16462        }
16463
16464        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16465        app.adjSource = null;
16466        app.adjTarget = null;
16467        app.empty = false;
16468        app.cached = false;
16469
16470        final int activitiesSize = app.activities.size();
16471
16472        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16473            // The max adjustment doesn't allow this app to be anything
16474            // below foreground, so it is not worth doing work for it.
16475            app.adjType = "fixed";
16476            app.adjSeq = mAdjSeq;
16477            app.curRawAdj = app.maxAdj;
16478            app.foregroundActivities = false;
16479            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16480            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16481            // System processes can do UI, and when they do we want to have
16482            // them trim their memory after the user leaves the UI.  To
16483            // facilitate this, here we need to determine whether or not it
16484            // is currently showing UI.
16485            app.systemNoUi = true;
16486            if (app == TOP_APP) {
16487                app.systemNoUi = false;
16488            } else if (activitiesSize > 0) {
16489                for (int j = 0; j < activitiesSize; j++) {
16490                    final ActivityRecord r = app.activities.get(j);
16491                    if (r.visible) {
16492                        app.systemNoUi = false;
16493                    }
16494                }
16495            }
16496            if (!app.systemNoUi) {
16497                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16498            }
16499            return (app.curAdj=app.maxAdj);
16500        }
16501
16502        app.systemNoUi = false;
16503
16504        // Determine the importance of the process, starting with most
16505        // important to least, and assign an appropriate OOM adjustment.
16506        int adj;
16507        int schedGroup;
16508        int procState;
16509        boolean foregroundActivities = false;
16510        BroadcastQueue queue;
16511        if (app == TOP_APP) {
16512            // The last app on the list is the foreground app.
16513            adj = ProcessList.FOREGROUND_APP_ADJ;
16514            schedGroup = Process.THREAD_GROUP_DEFAULT;
16515            app.adjType = "top-activity";
16516            foregroundActivities = true;
16517            procState = ActivityManager.PROCESS_STATE_TOP;
16518        } else if (app.instrumentationClass != null) {
16519            // Don't want to kill running instrumentation.
16520            adj = ProcessList.FOREGROUND_APP_ADJ;
16521            schedGroup = Process.THREAD_GROUP_DEFAULT;
16522            app.adjType = "instrumentation";
16523            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16524        } else if ((queue = isReceivingBroadcast(app)) != null) {
16525            // An app that is currently receiving a broadcast also
16526            // counts as being in the foreground for OOM killer purposes.
16527            // It's placed in a sched group based on the nature of the
16528            // broadcast as reflected by which queue it's active in.
16529            adj = ProcessList.FOREGROUND_APP_ADJ;
16530            schedGroup = (queue == mFgBroadcastQueue)
16531                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16532            app.adjType = "broadcast";
16533            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16534        } else if (app.executingServices.size() > 0) {
16535            // An app that is currently executing a service callback also
16536            // counts as being in the foreground.
16537            adj = ProcessList.FOREGROUND_APP_ADJ;
16538            schedGroup = app.execServicesFg ?
16539                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16540            app.adjType = "exec-service";
16541            procState = ActivityManager.PROCESS_STATE_SERVICE;
16542            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16543        } else {
16544            // As far as we know the process is empty.  We may change our mind later.
16545            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16546            // At this point we don't actually know the adjustment.  Use the cached adj
16547            // value that the caller wants us to.
16548            adj = cachedAdj;
16549            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16550            app.cached = true;
16551            app.empty = true;
16552            app.adjType = "cch-empty";
16553        }
16554
16555        // Examine all activities if not already foreground.
16556        if (!foregroundActivities && activitiesSize > 0) {
16557            for (int j = 0; j < activitiesSize; j++) {
16558                final ActivityRecord r = app.activities.get(j);
16559                if (r.app != app) {
16560                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16561                            + app + "?!?");
16562                    continue;
16563                }
16564                if (r.visible) {
16565                    // App has a visible activity; only upgrade adjustment.
16566                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16567                        adj = ProcessList.VISIBLE_APP_ADJ;
16568                        app.adjType = "visible";
16569                    }
16570                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16571                        procState = ActivityManager.PROCESS_STATE_TOP;
16572                    }
16573                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16574                    app.cached = false;
16575                    app.empty = false;
16576                    foregroundActivities = true;
16577                    break;
16578                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16579                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16580                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16581                        app.adjType = "pausing";
16582                    }
16583                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16584                        procState = ActivityManager.PROCESS_STATE_TOP;
16585                    }
16586                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16587                    app.cached = false;
16588                    app.empty = false;
16589                    foregroundActivities = true;
16590                } else if (r.state == ActivityState.STOPPING) {
16591                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16592                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16593                        app.adjType = "stopping";
16594                    }
16595                    // For the process state, we will at this point consider the
16596                    // process to be cached.  It will be cached either as an activity
16597                    // or empty depending on whether the activity is finishing.  We do
16598                    // this so that we can treat the process as cached for purposes of
16599                    // memory trimming (determing current memory level, trim command to
16600                    // send to process) since there can be an arbitrary number of stopping
16601                    // processes and they should soon all go into the cached state.
16602                    if (!r.finishing) {
16603                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16604                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16605                        }
16606                    }
16607                    app.cached = false;
16608                    app.empty = false;
16609                    foregroundActivities = true;
16610                } else {
16611                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16612                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16613                        app.adjType = "cch-act";
16614                    }
16615                }
16616            }
16617        }
16618
16619        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16620            if (app.foregroundServices) {
16621                // The user is aware of this app, so make it visible.
16622                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16623                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16624                app.cached = false;
16625                app.adjType = "fg-service";
16626                schedGroup = Process.THREAD_GROUP_DEFAULT;
16627            } else if (app.forcingToForeground != null) {
16628                // The user is aware of this app, so make it visible.
16629                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16630                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16631                app.cached = false;
16632                app.adjType = "force-fg";
16633                app.adjSource = app.forcingToForeground;
16634                schedGroup = Process.THREAD_GROUP_DEFAULT;
16635            }
16636        }
16637
16638        if (app == mHeavyWeightProcess) {
16639            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16640                // We don't want to kill the current heavy-weight process.
16641                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16642                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16643                app.cached = false;
16644                app.adjType = "heavy";
16645            }
16646            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16647                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16648            }
16649        }
16650
16651        if (app == mHomeProcess) {
16652            if (adj > ProcessList.HOME_APP_ADJ) {
16653                // This process is hosting what we currently consider to be the
16654                // home app, so we don't want to let it go into the background.
16655                adj = ProcessList.HOME_APP_ADJ;
16656                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16657                app.cached = false;
16658                app.adjType = "home";
16659            }
16660            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16661                procState = ActivityManager.PROCESS_STATE_HOME;
16662            }
16663        }
16664
16665        if (app == mPreviousProcess && app.activities.size() > 0) {
16666            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16667                // This was the previous process that showed UI to the user.
16668                // We want to try to keep it around more aggressively, to give
16669                // a good experience around switching between two apps.
16670                adj = ProcessList.PREVIOUS_APP_ADJ;
16671                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16672                app.cached = false;
16673                app.adjType = "previous";
16674            }
16675            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16676                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16677            }
16678        }
16679
16680        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16681                + " reason=" + app.adjType);
16682
16683        // By default, we use the computed adjustment.  It may be changed if
16684        // there are applications dependent on our services or providers, but
16685        // this gives us a baseline and makes sure we don't get into an
16686        // infinite recursion.
16687        app.adjSeq = mAdjSeq;
16688        app.curRawAdj = adj;
16689        app.hasStartedServices = false;
16690
16691        if (mBackupTarget != null && app == mBackupTarget.app) {
16692            // If possible we want to avoid killing apps while they're being backed up
16693            if (adj > ProcessList.BACKUP_APP_ADJ) {
16694                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16695                adj = ProcessList.BACKUP_APP_ADJ;
16696                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16697                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16698                }
16699                app.adjType = "backup";
16700                app.cached = false;
16701            }
16702            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16703                procState = ActivityManager.PROCESS_STATE_BACKUP;
16704            }
16705        }
16706
16707        boolean mayBeTop = false;
16708
16709        for (int is = app.services.size()-1;
16710                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16711                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16712                        || procState > ActivityManager.PROCESS_STATE_TOP);
16713                is--) {
16714            ServiceRecord s = app.services.valueAt(is);
16715            if (s.startRequested) {
16716                app.hasStartedServices = true;
16717                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16718                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16719                }
16720                if (app.hasShownUi && app != mHomeProcess) {
16721                    // If this process has shown some UI, let it immediately
16722                    // go to the LRU list because it may be pretty heavy with
16723                    // UI stuff.  We'll tag it with a label just to help
16724                    // debug and understand what is going on.
16725                    if (adj > ProcessList.SERVICE_ADJ) {
16726                        app.adjType = "cch-started-ui-services";
16727                    }
16728                } else {
16729                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16730                        // This service has seen some activity within
16731                        // recent memory, so we will keep its process ahead
16732                        // of the background processes.
16733                        if (adj > ProcessList.SERVICE_ADJ) {
16734                            adj = ProcessList.SERVICE_ADJ;
16735                            app.adjType = "started-services";
16736                            app.cached = false;
16737                        }
16738                    }
16739                    // If we have let the service slide into the background
16740                    // state, still have some text describing what it is doing
16741                    // even though the service no longer has an impact.
16742                    if (adj > ProcessList.SERVICE_ADJ) {
16743                        app.adjType = "cch-started-services";
16744                    }
16745                }
16746            }
16747            for (int conni = s.connections.size()-1;
16748                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16749                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16750                            || procState > ActivityManager.PROCESS_STATE_TOP);
16751                    conni--) {
16752                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16753                for (int i = 0;
16754                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16755                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16756                                || procState > ActivityManager.PROCESS_STATE_TOP);
16757                        i++) {
16758                    // XXX should compute this based on the max of
16759                    // all connected clients.
16760                    ConnectionRecord cr = clist.get(i);
16761                    if (cr.binding.client == app) {
16762                        // Binding to ourself is not interesting.
16763                        continue;
16764                    }
16765                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16766                        ProcessRecord client = cr.binding.client;
16767                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16768                                TOP_APP, doingAll, now);
16769                        int clientProcState = client.curProcState;
16770                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16771                            // If the other app is cached for any reason, for purposes here
16772                            // we are going to consider it empty.  The specific cached state
16773                            // doesn't propagate except under certain conditions.
16774                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16775                        }
16776                        String adjType = null;
16777                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16778                            // Not doing bind OOM management, so treat
16779                            // this guy more like a started service.
16780                            if (app.hasShownUi && app != mHomeProcess) {
16781                                // If this process has shown some UI, let it immediately
16782                                // go to the LRU list because it may be pretty heavy with
16783                                // UI stuff.  We'll tag it with a label just to help
16784                                // debug and understand what is going on.
16785                                if (adj > clientAdj) {
16786                                    adjType = "cch-bound-ui-services";
16787                                }
16788                                app.cached = false;
16789                                clientAdj = adj;
16790                                clientProcState = procState;
16791                            } else {
16792                                if (now >= (s.lastActivity
16793                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16794                                    // This service has not seen activity within
16795                                    // recent memory, so allow it to drop to the
16796                                    // LRU list if there is no other reason to keep
16797                                    // it around.  We'll also tag it with a label just
16798                                    // to help debug and undertand what is going on.
16799                                    if (adj > clientAdj) {
16800                                        adjType = "cch-bound-services";
16801                                    }
16802                                    clientAdj = adj;
16803                                }
16804                            }
16805                        }
16806                        if (adj > clientAdj) {
16807                            // If this process has recently shown UI, and
16808                            // the process that is binding to it is less
16809                            // important than being visible, then we don't
16810                            // care about the binding as much as we care
16811                            // about letting this process get into the LRU
16812                            // list to be killed and restarted if needed for
16813                            // memory.
16814                            if (app.hasShownUi && app != mHomeProcess
16815                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16816                                adjType = "cch-bound-ui-services";
16817                            } else {
16818                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16819                                        |Context.BIND_IMPORTANT)) != 0) {
16820                                    adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16821                                            ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16822                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16823                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16824                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16825                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16826                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16827                                    adj = clientAdj;
16828                                } else {
16829                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16830                                        adj = ProcessList.VISIBLE_APP_ADJ;
16831                                    }
16832                                }
16833                                if (!client.cached) {
16834                                    app.cached = false;
16835                                }
16836                                adjType = "service";
16837                            }
16838                        }
16839                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16840                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16841                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16842                            }
16843                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16844                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16845                                    // Special handling of clients who are in the top state.
16846                                    // We *may* want to consider this process to be in the
16847                                    // top state as well, but only if there is not another
16848                                    // reason for it to be running.  Being on the top is a
16849                                    // special state, meaning you are specifically running
16850                                    // for the current top app.  If the process is already
16851                                    // running in the background for some other reason, it
16852                                    // is more important to continue considering it to be
16853                                    // in the background state.
16854                                    mayBeTop = true;
16855                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16856                                } else {
16857                                    // Special handling for above-top states (persistent
16858                                    // processes).  These should not bring the current process
16859                                    // into the top state, since they are not on top.  Instead
16860                                    // give them the best state after that.
16861                                    clientProcState =
16862                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16863                                }
16864                            }
16865                        } else {
16866                            if (clientProcState <
16867                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16868                                clientProcState =
16869                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16870                            }
16871                        }
16872                        if (procState > clientProcState) {
16873                            procState = clientProcState;
16874                        }
16875                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16876                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16877                            app.pendingUiClean = true;
16878                        }
16879                        if (adjType != null) {
16880                            app.adjType = adjType;
16881                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16882                                    .REASON_SERVICE_IN_USE;
16883                            app.adjSource = cr.binding.client;
16884                            app.adjSourceProcState = clientProcState;
16885                            app.adjTarget = s.name;
16886                        }
16887                    }
16888                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16889                        app.treatLikeActivity = true;
16890                    }
16891                    final ActivityRecord a = cr.activity;
16892                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16893                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16894                                (a.visible || a.state == ActivityState.RESUMED
16895                                 || a.state == ActivityState.PAUSING)) {
16896                            adj = ProcessList.FOREGROUND_APP_ADJ;
16897                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16898                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16899                            }
16900                            app.cached = false;
16901                            app.adjType = "service";
16902                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16903                                    .REASON_SERVICE_IN_USE;
16904                            app.adjSource = a;
16905                            app.adjSourceProcState = procState;
16906                            app.adjTarget = s.name;
16907                        }
16908                    }
16909                }
16910            }
16911        }
16912
16913        for (int provi = app.pubProviders.size()-1;
16914                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16915                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16916                        || procState > ActivityManager.PROCESS_STATE_TOP);
16917                provi--) {
16918            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16919            for (int i = cpr.connections.size()-1;
16920                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16921                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16922                            || procState > ActivityManager.PROCESS_STATE_TOP);
16923                    i--) {
16924                ContentProviderConnection conn = cpr.connections.get(i);
16925                ProcessRecord client = conn.client;
16926                if (client == app) {
16927                    // Being our own client is not interesting.
16928                    continue;
16929                }
16930                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16931                int clientProcState = client.curProcState;
16932                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16933                    // If the other app is cached for any reason, for purposes here
16934                    // we are going to consider it empty.
16935                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16936                }
16937                if (adj > clientAdj) {
16938                    if (app.hasShownUi && app != mHomeProcess
16939                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16940                        app.adjType = "cch-ui-provider";
16941                    } else {
16942                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16943                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16944                        app.adjType = "provider";
16945                    }
16946                    app.cached &= client.cached;
16947                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16948                            .REASON_PROVIDER_IN_USE;
16949                    app.adjSource = client;
16950                    app.adjSourceProcState = clientProcState;
16951                    app.adjTarget = cpr.name;
16952                }
16953                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16954                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16955                        // Special handling of clients who are in the top state.
16956                        // We *may* want to consider this process to be in the
16957                        // top state as well, but only if there is not another
16958                        // reason for it to be running.  Being on the top is a
16959                        // special state, meaning you are specifically running
16960                        // for the current top app.  If the process is already
16961                        // running in the background for some other reason, it
16962                        // is more important to continue considering it to be
16963                        // in the background state.
16964                        mayBeTop = true;
16965                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16966                    } else {
16967                        // Special handling for above-top states (persistent
16968                        // processes).  These should not bring the current process
16969                        // into the top state, since they are not on top.  Instead
16970                        // give them the best state after that.
16971                        clientProcState =
16972                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16973                    }
16974                }
16975                if (procState > clientProcState) {
16976                    procState = clientProcState;
16977                }
16978                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16979                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16980                }
16981            }
16982            // If the provider has external (non-framework) process
16983            // dependencies, ensure that its adjustment is at least
16984            // FOREGROUND_APP_ADJ.
16985            if (cpr.hasExternalProcessHandles()) {
16986                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16987                    adj = ProcessList.FOREGROUND_APP_ADJ;
16988                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16989                    app.cached = false;
16990                    app.adjType = "provider";
16991                    app.adjTarget = cpr.name;
16992                }
16993                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16994                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16995                }
16996            }
16997        }
16998
16999        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17000            // A client of one of our services or providers is in the top state.  We
17001            // *may* want to be in the top state, but not if we are already running in
17002            // the background for some other reason.  For the decision here, we are going
17003            // to pick out a few specific states that we want to remain in when a client
17004            // is top (states that tend to be longer-term) and otherwise allow it to go
17005            // to the top state.
17006            switch (procState) {
17007                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17008                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17009                case ActivityManager.PROCESS_STATE_SERVICE:
17010                    // These all are longer-term states, so pull them up to the top
17011                    // of the background states, but not all the way to the top state.
17012                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17013                    break;
17014                default:
17015                    // Otherwise, top is a better choice, so take it.
17016                    procState = ActivityManager.PROCESS_STATE_TOP;
17017                    break;
17018            }
17019        }
17020
17021        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17022            if (app.hasClientActivities) {
17023                // This is a cached process, but with client activities.  Mark it so.
17024                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17025                app.adjType = "cch-client-act";
17026            } else if (app.treatLikeActivity) {
17027                // This is a cached process, but somebody wants us to treat it like it has
17028                // an activity, okay!
17029                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17030                app.adjType = "cch-as-act";
17031            }
17032        }
17033
17034        if (adj == ProcessList.SERVICE_ADJ) {
17035            if (doingAll) {
17036                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17037                mNewNumServiceProcs++;
17038                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17039                if (!app.serviceb) {
17040                    // This service isn't far enough down on the LRU list to
17041                    // normally be a B service, but if we are low on RAM and it
17042                    // is large we want to force it down since we would prefer to
17043                    // keep launcher over it.
17044                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17045                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17046                        app.serviceHighRam = true;
17047                        app.serviceb = true;
17048                        //Slog.i(TAG, "ADJ " + app + " high ram!");
17049                    } else {
17050                        mNewNumAServiceProcs++;
17051                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
17052                    }
17053                } else {
17054                    app.serviceHighRam = false;
17055                }
17056            }
17057            if (app.serviceb) {
17058                adj = ProcessList.SERVICE_B_ADJ;
17059            }
17060        }
17061
17062        app.curRawAdj = adj;
17063
17064        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17065        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17066        if (adj > app.maxAdj) {
17067            adj = app.maxAdj;
17068            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17069                schedGroup = Process.THREAD_GROUP_DEFAULT;
17070            }
17071        }
17072
17073        // Do final modification to adj.  Everything we do between here and applying
17074        // the final setAdj must be done in this function, because we will also use
17075        // it when computing the final cached adj later.  Note that we don't need to
17076        // worry about this for max adj above, since max adj will always be used to
17077        // keep it out of the cached vaues.
17078        app.curAdj = app.modifyRawOomAdj(adj);
17079        app.curSchedGroup = schedGroup;
17080        app.curProcState = procState;
17081        app.foregroundActivities = foregroundActivities;
17082
17083        return app.curRawAdj;
17084    }
17085
17086    /**
17087     * Schedule PSS collection of a process.
17088     */
17089    void requestPssLocked(ProcessRecord proc, int procState) {
17090        if (mPendingPssProcesses.contains(proc)) {
17091            return;
17092        }
17093        if (mPendingPssProcesses.size() == 0) {
17094            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17095        }
17096        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17097        proc.pssProcState = procState;
17098        mPendingPssProcesses.add(proc);
17099    }
17100
17101    /**
17102     * Schedule PSS collection of all processes.
17103     */
17104    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17105        if (!always) {
17106            if (now < (mLastFullPssTime +
17107                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17108                return;
17109            }
17110        }
17111        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17112        mLastFullPssTime = now;
17113        mFullPssPending = true;
17114        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17115        mPendingPssProcesses.clear();
17116        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17117            ProcessRecord app = mLruProcesses.get(i);
17118            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17119                app.pssProcState = app.setProcState;
17120                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17121                        isSleeping(), now);
17122                mPendingPssProcesses.add(app);
17123            }
17124        }
17125        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17126    }
17127
17128    /**
17129     * Ask a given process to GC right now.
17130     */
17131    final void performAppGcLocked(ProcessRecord app) {
17132        try {
17133            app.lastRequestedGc = SystemClock.uptimeMillis();
17134            if (app.thread != null) {
17135                if (app.reportLowMemory) {
17136                    app.reportLowMemory = false;
17137                    app.thread.scheduleLowMemory();
17138                } else {
17139                    app.thread.processInBackground();
17140                }
17141            }
17142        } catch (Exception e) {
17143            // whatever.
17144        }
17145    }
17146
17147    /**
17148     * Returns true if things are idle enough to perform GCs.
17149     */
17150    private final boolean canGcNowLocked() {
17151        boolean processingBroadcasts = false;
17152        for (BroadcastQueue q : mBroadcastQueues) {
17153            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17154                processingBroadcasts = true;
17155            }
17156        }
17157        return !processingBroadcasts
17158                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17159    }
17160
17161    /**
17162     * Perform GCs on all processes that are waiting for it, but only
17163     * if things are idle.
17164     */
17165    final void performAppGcsLocked() {
17166        final int N = mProcessesToGc.size();
17167        if (N <= 0) {
17168            return;
17169        }
17170        if (canGcNowLocked()) {
17171            while (mProcessesToGc.size() > 0) {
17172                ProcessRecord proc = mProcessesToGc.remove(0);
17173                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17174                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17175                            <= SystemClock.uptimeMillis()) {
17176                        // To avoid spamming the system, we will GC processes one
17177                        // at a time, waiting a few seconds between each.
17178                        performAppGcLocked(proc);
17179                        scheduleAppGcsLocked();
17180                        return;
17181                    } else {
17182                        // It hasn't been long enough since we last GCed this
17183                        // process...  put it in the list to wait for its time.
17184                        addProcessToGcListLocked(proc);
17185                        break;
17186                    }
17187                }
17188            }
17189
17190            scheduleAppGcsLocked();
17191        }
17192    }
17193
17194    /**
17195     * If all looks good, perform GCs on all processes waiting for them.
17196     */
17197    final void performAppGcsIfAppropriateLocked() {
17198        if (canGcNowLocked()) {
17199            performAppGcsLocked();
17200            return;
17201        }
17202        // Still not idle, wait some more.
17203        scheduleAppGcsLocked();
17204    }
17205
17206    /**
17207     * Schedule the execution of all pending app GCs.
17208     */
17209    final void scheduleAppGcsLocked() {
17210        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17211
17212        if (mProcessesToGc.size() > 0) {
17213            // Schedule a GC for the time to the next process.
17214            ProcessRecord proc = mProcessesToGc.get(0);
17215            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17216
17217            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17218            long now = SystemClock.uptimeMillis();
17219            if (when < (now+GC_TIMEOUT)) {
17220                when = now + GC_TIMEOUT;
17221            }
17222            mHandler.sendMessageAtTime(msg, when);
17223        }
17224    }
17225
17226    /**
17227     * Add a process to the array of processes waiting to be GCed.  Keeps the
17228     * list in sorted order by the last GC time.  The process can't already be
17229     * on the list.
17230     */
17231    final void addProcessToGcListLocked(ProcessRecord proc) {
17232        boolean added = false;
17233        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17234            if (mProcessesToGc.get(i).lastRequestedGc <
17235                    proc.lastRequestedGc) {
17236                added = true;
17237                mProcessesToGc.add(i+1, proc);
17238                break;
17239            }
17240        }
17241        if (!added) {
17242            mProcessesToGc.add(0, proc);
17243        }
17244    }
17245
17246    /**
17247     * Set up to ask a process to GC itself.  This will either do it
17248     * immediately, or put it on the list of processes to gc the next
17249     * time things are idle.
17250     */
17251    final void scheduleAppGcLocked(ProcessRecord app) {
17252        long now = SystemClock.uptimeMillis();
17253        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17254            return;
17255        }
17256        if (!mProcessesToGc.contains(app)) {
17257            addProcessToGcListLocked(app);
17258            scheduleAppGcsLocked();
17259        }
17260    }
17261
17262    final void checkExcessivePowerUsageLocked(boolean doKills) {
17263        updateCpuStatsNow();
17264
17265        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17266        boolean doWakeKills = doKills;
17267        boolean doCpuKills = doKills;
17268        if (mLastPowerCheckRealtime == 0) {
17269            doWakeKills = false;
17270        }
17271        if (mLastPowerCheckUptime == 0) {
17272            doCpuKills = false;
17273        }
17274        if (stats.isScreenOn()) {
17275            doWakeKills = false;
17276        }
17277        final long curRealtime = SystemClock.elapsedRealtime();
17278        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17279        final long curUptime = SystemClock.uptimeMillis();
17280        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17281        mLastPowerCheckRealtime = curRealtime;
17282        mLastPowerCheckUptime = curUptime;
17283        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17284            doWakeKills = false;
17285        }
17286        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17287            doCpuKills = false;
17288        }
17289        int i = mLruProcesses.size();
17290        while (i > 0) {
17291            i--;
17292            ProcessRecord app = mLruProcesses.get(i);
17293            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17294                long wtime;
17295                synchronized (stats) {
17296                    wtime = stats.getProcessWakeTime(app.info.uid,
17297                            app.pid, curRealtime);
17298                }
17299                long wtimeUsed = wtime - app.lastWakeTime;
17300                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17301                if (DEBUG_POWER) {
17302                    StringBuilder sb = new StringBuilder(128);
17303                    sb.append("Wake for ");
17304                    app.toShortString(sb);
17305                    sb.append(": over ");
17306                    TimeUtils.formatDuration(realtimeSince, sb);
17307                    sb.append(" used ");
17308                    TimeUtils.formatDuration(wtimeUsed, sb);
17309                    sb.append(" (");
17310                    sb.append((wtimeUsed*100)/realtimeSince);
17311                    sb.append("%)");
17312                    Slog.i(TAG, sb.toString());
17313                    sb.setLength(0);
17314                    sb.append("CPU for ");
17315                    app.toShortString(sb);
17316                    sb.append(": over ");
17317                    TimeUtils.formatDuration(uptimeSince, sb);
17318                    sb.append(" used ");
17319                    TimeUtils.formatDuration(cputimeUsed, sb);
17320                    sb.append(" (");
17321                    sb.append((cputimeUsed*100)/uptimeSince);
17322                    sb.append("%)");
17323                    Slog.i(TAG, sb.toString());
17324                }
17325                // If a process has held a wake lock for more
17326                // than 50% of the time during this period,
17327                // that sounds bad.  Kill!
17328                if (doWakeKills && realtimeSince > 0
17329                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17330                    synchronized (stats) {
17331                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17332                                realtimeSince, wtimeUsed);
17333                    }
17334                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17335                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17336                } else if (doCpuKills && uptimeSince > 0
17337                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17338                    synchronized (stats) {
17339                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17340                                uptimeSince, cputimeUsed);
17341                    }
17342                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17343                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17344                } else {
17345                    app.lastWakeTime = wtime;
17346                    app.lastCpuTime = app.curCpuTime;
17347                }
17348            }
17349        }
17350    }
17351
17352    private final boolean applyOomAdjLocked(ProcessRecord app,
17353            ProcessRecord TOP_APP, boolean doingAll, long now) {
17354        boolean success = true;
17355
17356        if (app.curRawAdj != app.setRawAdj) {
17357            app.setRawAdj = app.curRawAdj;
17358        }
17359
17360        int changes = 0;
17361
17362        if (app.curAdj != app.setAdj) {
17363            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17364            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17365                TAG, "Set " + app.pid + " " + app.processName +
17366                " adj " + app.curAdj + ": " + app.adjType);
17367            app.setAdj = app.curAdj;
17368        }
17369
17370        if (app.setSchedGroup != app.curSchedGroup) {
17371            app.setSchedGroup = app.curSchedGroup;
17372            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17373                    "Setting process group of " + app.processName
17374                    + " to " + app.curSchedGroup);
17375            if (app.waitingToKill != null &&
17376                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17377                app.kill(app.waitingToKill, true);
17378                success = false;
17379            } else {
17380                if (true) {
17381                    long oldId = Binder.clearCallingIdentity();
17382                    try {
17383                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17384                    } catch (Exception e) {
17385                        Slog.w(TAG, "Failed setting process group of " + app.pid
17386                                + " to " + app.curSchedGroup);
17387                        e.printStackTrace();
17388                    } finally {
17389                        Binder.restoreCallingIdentity(oldId);
17390                    }
17391                } else {
17392                    if (app.thread != null) {
17393                        try {
17394                            app.thread.setSchedulingGroup(app.curSchedGroup);
17395                        } catch (RemoteException e) {
17396                        }
17397                    }
17398                }
17399                Process.setSwappiness(app.pid,
17400                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17401            }
17402        }
17403        if (app.repForegroundActivities != app.foregroundActivities) {
17404            app.repForegroundActivities = app.foregroundActivities;
17405            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17406        }
17407        if (app.repProcState != app.curProcState) {
17408            app.repProcState = app.curProcState;
17409            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17410            if (app.thread != null) {
17411                try {
17412                    if (false) {
17413                        //RuntimeException h = new RuntimeException("here");
17414                        Slog.i(TAG, "Sending new process state " + app.repProcState
17415                                + " to " + app /*, h*/);
17416                    }
17417                    app.thread.setProcessState(app.repProcState);
17418                } catch (RemoteException e) {
17419                }
17420            }
17421        }
17422        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17423                app.setProcState)) {
17424            app.lastStateTime = now;
17425            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17426                    isSleeping(), now);
17427            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17428                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17429                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17430                    + (app.nextPssTime-now) + ": " + app);
17431        } else {
17432            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17433                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17434                requestPssLocked(app, app.setProcState);
17435                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17436                        isSleeping(), now);
17437            } else if (false && DEBUG_PSS) {
17438                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17439            }
17440        }
17441        if (app.setProcState != app.curProcState) {
17442            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17443                    "Proc state change of " + app.processName
17444                    + " to " + app.curProcState);
17445            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17446            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17447            if (setImportant && !curImportant) {
17448                // This app is no longer something we consider important enough to allow to
17449                // use arbitrary amounts of battery power.  Note
17450                // its current wake lock time to later know to kill it if
17451                // it is not behaving well.
17452                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17453                synchronized (stats) {
17454                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17455                            app.pid, SystemClock.elapsedRealtime());
17456                }
17457                app.lastCpuTime = app.curCpuTime;
17458
17459            }
17460            app.setProcState = app.curProcState;
17461            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17462                app.notCachedSinceIdle = false;
17463            }
17464            if (!doingAll) {
17465                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17466            } else {
17467                app.procStateChanged = true;
17468            }
17469        }
17470
17471        if (changes != 0) {
17472            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17473            int i = mPendingProcessChanges.size()-1;
17474            ProcessChangeItem item = null;
17475            while (i >= 0) {
17476                item = mPendingProcessChanges.get(i);
17477                if (item.pid == app.pid) {
17478                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17479                    break;
17480                }
17481                i--;
17482            }
17483            if (i < 0) {
17484                // No existing item in pending changes; need a new one.
17485                final int NA = mAvailProcessChanges.size();
17486                if (NA > 0) {
17487                    item = mAvailProcessChanges.remove(NA-1);
17488                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17489                } else {
17490                    item = new ProcessChangeItem();
17491                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17492                }
17493                item.changes = 0;
17494                item.pid = app.pid;
17495                item.uid = app.info.uid;
17496                if (mPendingProcessChanges.size() == 0) {
17497                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17498                            "*** Enqueueing dispatch processes changed!");
17499                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17500                }
17501                mPendingProcessChanges.add(item);
17502            }
17503            item.changes |= changes;
17504            item.processState = app.repProcState;
17505            item.foregroundActivities = app.repForegroundActivities;
17506            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17507                    + Integer.toHexString(System.identityHashCode(item))
17508                    + " " + app.toShortString() + ": changes=" + item.changes
17509                    + " procState=" + item.processState
17510                    + " foreground=" + item.foregroundActivities
17511                    + " type=" + app.adjType + " source=" + app.adjSource
17512                    + " target=" + app.adjTarget);
17513        }
17514
17515        return success;
17516    }
17517
17518    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17519        if (proc.thread != null) {
17520            if (proc.baseProcessTracker != null) {
17521                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17522            }
17523            if (proc.repProcState >= 0) {
17524                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17525                        proc.repProcState);
17526            }
17527        }
17528    }
17529
17530    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17531            ProcessRecord TOP_APP, boolean doingAll, long now) {
17532        if (app.thread == null) {
17533            return false;
17534        }
17535
17536        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17537
17538        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17539    }
17540
17541    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17542            boolean oomAdj) {
17543        if (isForeground != proc.foregroundServices) {
17544            proc.foregroundServices = isForeground;
17545            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17546                    proc.info.uid);
17547            if (isForeground) {
17548                if (curProcs == null) {
17549                    curProcs = new ArrayList<ProcessRecord>();
17550                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17551                }
17552                if (!curProcs.contains(proc)) {
17553                    curProcs.add(proc);
17554                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17555                            proc.info.packageName, proc.info.uid);
17556                }
17557            } else {
17558                if (curProcs != null) {
17559                    if (curProcs.remove(proc)) {
17560                        mBatteryStatsService.noteEvent(
17561                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17562                                proc.info.packageName, proc.info.uid);
17563                        if (curProcs.size() <= 0) {
17564                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17565                        }
17566                    }
17567                }
17568            }
17569            if (oomAdj) {
17570                updateOomAdjLocked();
17571            }
17572        }
17573    }
17574
17575    private final ActivityRecord resumedAppLocked() {
17576        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17577        String pkg;
17578        int uid;
17579        if (act != null) {
17580            pkg = act.packageName;
17581            uid = act.info.applicationInfo.uid;
17582        } else {
17583            pkg = null;
17584            uid = -1;
17585        }
17586        // Has the UID or resumed package name changed?
17587        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17588                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17589            if (mCurResumedPackage != null) {
17590                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17591                        mCurResumedPackage, mCurResumedUid);
17592            }
17593            mCurResumedPackage = pkg;
17594            mCurResumedUid = uid;
17595            if (mCurResumedPackage != null) {
17596                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17597                        mCurResumedPackage, mCurResumedUid);
17598            }
17599        }
17600        return act;
17601    }
17602
17603    final boolean updateOomAdjLocked(ProcessRecord app) {
17604        final ActivityRecord TOP_ACT = resumedAppLocked();
17605        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17606        final boolean wasCached = app.cached;
17607
17608        mAdjSeq++;
17609
17610        // This is the desired cached adjusment we want to tell it to use.
17611        // If our app is currently cached, we know it, and that is it.  Otherwise,
17612        // we don't know it yet, and it needs to now be cached we will then
17613        // need to do a complete oom adj.
17614        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17615                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17616        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17617                SystemClock.uptimeMillis());
17618        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17619            // Changed to/from cached state, so apps after it in the LRU
17620            // list may also be changed.
17621            updateOomAdjLocked();
17622        }
17623        return success;
17624    }
17625
17626    final void updateOomAdjLocked() {
17627        final ActivityRecord TOP_ACT = resumedAppLocked();
17628        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17629        final long now = SystemClock.uptimeMillis();
17630        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17631        final int N = mLruProcesses.size();
17632
17633        if (false) {
17634            RuntimeException e = new RuntimeException();
17635            e.fillInStackTrace();
17636            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17637        }
17638
17639        mAdjSeq++;
17640        mNewNumServiceProcs = 0;
17641        mNewNumAServiceProcs = 0;
17642
17643        final int emptyProcessLimit;
17644        final int cachedProcessLimit;
17645        if (mProcessLimit <= 0) {
17646            emptyProcessLimit = cachedProcessLimit = 0;
17647        } else if (mProcessLimit == 1) {
17648            emptyProcessLimit = 1;
17649            cachedProcessLimit = 0;
17650        } else {
17651            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17652            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17653        }
17654
17655        // Let's determine how many processes we have running vs.
17656        // how many slots we have for background processes; we may want
17657        // to put multiple processes in a slot of there are enough of
17658        // them.
17659        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17660                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17661        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17662        if (numEmptyProcs > cachedProcessLimit) {
17663            // If there are more empty processes than our limit on cached
17664            // processes, then use the cached process limit for the factor.
17665            // This ensures that the really old empty processes get pushed
17666            // down to the bottom, so if we are running low on memory we will
17667            // have a better chance at keeping around more cached processes
17668            // instead of a gazillion empty processes.
17669            numEmptyProcs = cachedProcessLimit;
17670        }
17671        int emptyFactor = numEmptyProcs/numSlots;
17672        if (emptyFactor < 1) emptyFactor = 1;
17673        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17674        if (cachedFactor < 1) cachedFactor = 1;
17675        int stepCached = 0;
17676        int stepEmpty = 0;
17677        int numCached = 0;
17678        int numEmpty = 0;
17679        int numTrimming = 0;
17680
17681        mNumNonCachedProcs = 0;
17682        mNumCachedHiddenProcs = 0;
17683
17684        // First update the OOM adjustment for each of the
17685        // application processes based on their current state.
17686        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17687        int nextCachedAdj = curCachedAdj+1;
17688        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17689        int nextEmptyAdj = curEmptyAdj+2;
17690        for (int i=N-1; i>=0; i--) {
17691            ProcessRecord app = mLruProcesses.get(i);
17692            if (!app.killedByAm && app.thread != null) {
17693                app.procStateChanged = false;
17694                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17695
17696                // If we haven't yet assigned the final cached adj
17697                // to the process, do that now.
17698                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17699                    switch (app.curProcState) {
17700                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17701                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17702                            // This process is a cached process holding activities...
17703                            // assign it the next cached value for that type, and then
17704                            // step that cached level.
17705                            app.curRawAdj = curCachedAdj;
17706                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17707                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17708                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17709                                    + ")");
17710                            if (curCachedAdj != nextCachedAdj) {
17711                                stepCached++;
17712                                if (stepCached >= cachedFactor) {
17713                                    stepCached = 0;
17714                                    curCachedAdj = nextCachedAdj;
17715                                    nextCachedAdj += 2;
17716                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17717                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17718                                    }
17719                                }
17720                            }
17721                            break;
17722                        default:
17723                            // For everything else, assign next empty cached process
17724                            // level and bump that up.  Note that this means that
17725                            // long-running services that have dropped down to the
17726                            // cached level will be treated as empty (since their process
17727                            // state is still as a service), which is what we want.
17728                            app.curRawAdj = curEmptyAdj;
17729                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17730                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17731                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17732                                    + ")");
17733                            if (curEmptyAdj != nextEmptyAdj) {
17734                                stepEmpty++;
17735                                if (stepEmpty >= emptyFactor) {
17736                                    stepEmpty = 0;
17737                                    curEmptyAdj = nextEmptyAdj;
17738                                    nextEmptyAdj += 2;
17739                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17740                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17741                                    }
17742                                }
17743                            }
17744                            break;
17745                    }
17746                }
17747
17748                applyOomAdjLocked(app, TOP_APP, true, now);
17749
17750                // Count the number of process types.
17751                switch (app.curProcState) {
17752                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17753                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17754                        mNumCachedHiddenProcs++;
17755                        numCached++;
17756                        if (numCached > cachedProcessLimit) {
17757                            app.kill("cached #" + numCached, true);
17758                        }
17759                        break;
17760                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17761                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17762                                && app.lastActivityTime < oldTime) {
17763                            app.kill("empty for "
17764                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17765                                    / 1000) + "s", true);
17766                        } else {
17767                            numEmpty++;
17768                            if (numEmpty > emptyProcessLimit) {
17769                                app.kill("empty #" + numEmpty, true);
17770                            }
17771                        }
17772                        break;
17773                    default:
17774                        mNumNonCachedProcs++;
17775                        break;
17776                }
17777
17778                if (app.isolated && app.services.size() <= 0) {
17779                    // If this is an isolated process, and there are no
17780                    // services running in it, then the process is no longer
17781                    // needed.  We agressively kill these because we can by
17782                    // definition not re-use the same process again, and it is
17783                    // good to avoid having whatever code was running in them
17784                    // left sitting around after no longer needed.
17785                    app.kill("isolated not needed", true);
17786                }
17787
17788                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17789                        && !app.killedByAm) {
17790                    numTrimming++;
17791                }
17792            }
17793        }
17794
17795        mNumServiceProcs = mNewNumServiceProcs;
17796
17797        // Now determine the memory trimming level of background processes.
17798        // Unfortunately we need to start at the back of the list to do this
17799        // properly.  We only do this if the number of background apps we
17800        // are managing to keep around is less than half the maximum we desire;
17801        // if we are keeping a good number around, we'll let them use whatever
17802        // memory they want.
17803        final int numCachedAndEmpty = numCached + numEmpty;
17804        int memFactor;
17805        if (numCached <= ProcessList.TRIM_CACHED_APPS
17806                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17807            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17808                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17809            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17810                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17811            } else {
17812                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17813            }
17814        } else {
17815            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17816        }
17817        // We always allow the memory level to go up (better).  We only allow it to go
17818        // down if we are in a state where that is allowed, *and* the total number of processes
17819        // has gone down since last time.
17820        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17821                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17822                + " last=" + mLastNumProcesses);
17823        if (memFactor > mLastMemoryLevel) {
17824            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17825                memFactor = mLastMemoryLevel;
17826                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17827            }
17828        }
17829        mLastMemoryLevel = memFactor;
17830        mLastNumProcesses = mLruProcesses.size();
17831        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17832        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17833        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17834            if (mLowRamStartTime == 0) {
17835                mLowRamStartTime = now;
17836            }
17837            int step = 0;
17838            int fgTrimLevel;
17839            switch (memFactor) {
17840                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17841                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17842                    break;
17843                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17844                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17845                    break;
17846                default:
17847                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17848                    break;
17849            }
17850            int factor = numTrimming/3;
17851            int minFactor = 2;
17852            if (mHomeProcess != null) minFactor++;
17853            if (mPreviousProcess != null) minFactor++;
17854            if (factor < minFactor) factor = minFactor;
17855            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17856            for (int i=N-1; i>=0; i--) {
17857                ProcessRecord app = mLruProcesses.get(i);
17858                if (allChanged || app.procStateChanged) {
17859                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17860                    app.procStateChanged = false;
17861                }
17862                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17863                        && !app.killedByAm) {
17864                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17865                        try {
17866                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17867                                    "Trimming memory of " + app.processName
17868                                    + " to " + curLevel);
17869                            app.thread.scheduleTrimMemory(curLevel);
17870                        } catch (RemoteException e) {
17871                        }
17872                        if (false) {
17873                            // For now we won't do this; our memory trimming seems
17874                            // to be good enough at this point that destroying
17875                            // activities causes more harm than good.
17876                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17877                                    && app != mHomeProcess && app != mPreviousProcess) {
17878                                // Need to do this on its own message because the stack may not
17879                                // be in a consistent state at this point.
17880                                // For these apps we will also finish their activities
17881                                // to help them free memory.
17882                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17883                            }
17884                        }
17885                    }
17886                    app.trimMemoryLevel = curLevel;
17887                    step++;
17888                    if (step >= factor) {
17889                        step = 0;
17890                        switch (curLevel) {
17891                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17892                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17893                                break;
17894                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17895                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17896                                break;
17897                        }
17898                    }
17899                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17900                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17901                            && app.thread != null) {
17902                        try {
17903                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17904                                    "Trimming memory of heavy-weight " + app.processName
17905                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17906                            app.thread.scheduleTrimMemory(
17907                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17908                        } catch (RemoteException e) {
17909                        }
17910                    }
17911                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17912                } else {
17913                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17914                            || app.systemNoUi) && app.pendingUiClean) {
17915                        // If this application is now in the background and it
17916                        // had done UI, then give it the special trim level to
17917                        // have it free UI resources.
17918                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17919                        if (app.trimMemoryLevel < level && app.thread != null) {
17920                            try {
17921                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17922                                        "Trimming memory of bg-ui " + app.processName
17923                                        + " to " + level);
17924                                app.thread.scheduleTrimMemory(level);
17925                            } catch (RemoteException e) {
17926                            }
17927                        }
17928                        app.pendingUiClean = false;
17929                    }
17930                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17931                        try {
17932                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17933                                    "Trimming memory of fg " + app.processName
17934                                    + " to " + fgTrimLevel);
17935                            app.thread.scheduleTrimMemory(fgTrimLevel);
17936                        } catch (RemoteException e) {
17937                        }
17938                    }
17939                    app.trimMemoryLevel = fgTrimLevel;
17940                }
17941            }
17942        } else {
17943            if (mLowRamStartTime != 0) {
17944                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17945                mLowRamStartTime = 0;
17946            }
17947            for (int i=N-1; i>=0; i--) {
17948                ProcessRecord app = mLruProcesses.get(i);
17949                if (allChanged || app.procStateChanged) {
17950                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17951                    app.procStateChanged = false;
17952                }
17953                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17954                        || app.systemNoUi) && app.pendingUiClean) {
17955                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17956                            && app.thread != null) {
17957                        try {
17958                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17959                                    "Trimming memory of ui hidden " + app.processName
17960                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17961                            app.thread.scheduleTrimMemory(
17962                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17963                        } catch (RemoteException e) {
17964                        }
17965                    }
17966                    app.pendingUiClean = false;
17967                }
17968                app.trimMemoryLevel = 0;
17969            }
17970        }
17971
17972        if (mAlwaysFinishActivities) {
17973            // Need to do this on its own message because the stack may not
17974            // be in a consistent state at this point.
17975            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17976        }
17977
17978        if (allChanged) {
17979            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17980        }
17981
17982        if (mProcessStats.shouldWriteNowLocked(now)) {
17983            mHandler.post(new Runnable() {
17984                @Override public void run() {
17985                    synchronized (ActivityManagerService.this) {
17986                        mProcessStats.writeStateAsyncLocked();
17987                    }
17988                }
17989            });
17990        }
17991
17992        if (DEBUG_OOM_ADJ) {
17993            if (false) {
17994                RuntimeException here = new RuntimeException("here");
17995                here.fillInStackTrace();
17996                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17997            } else {
17998                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17999            }
18000        }
18001    }
18002
18003    final void trimApplications() {
18004        synchronized (this) {
18005            int i;
18006
18007            // First remove any unused application processes whose package
18008            // has been removed.
18009            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18010                final ProcessRecord app = mRemovedProcesses.get(i);
18011                if (app.activities.size() == 0
18012                        && app.curReceiver == null && app.services.size() == 0) {
18013                    Slog.i(
18014                        TAG, "Exiting empty application process "
18015                        + app.processName + " ("
18016                        + (app.thread != null ? app.thread.asBinder() : null)
18017                        + ")\n");
18018                    if (app.pid > 0 && app.pid != MY_PID) {
18019                        app.kill("empty", false);
18020                    } else {
18021                        try {
18022                            app.thread.scheduleExit();
18023                        } catch (Exception e) {
18024                            // Ignore exceptions.
18025                        }
18026                    }
18027                    cleanUpApplicationRecordLocked(app, false, true, -1);
18028                    mRemovedProcesses.remove(i);
18029
18030                    if (app.persistent) {
18031                        addAppLocked(app.info, false, null /* ABI override */);
18032                    }
18033                }
18034            }
18035
18036            // Now update the oom adj for all processes.
18037            updateOomAdjLocked();
18038        }
18039    }
18040
18041    /** This method sends the specified signal to each of the persistent apps */
18042    public void signalPersistentProcesses(int sig) throws RemoteException {
18043        if (sig != Process.SIGNAL_USR1) {
18044            throw new SecurityException("Only SIGNAL_USR1 is allowed");
18045        }
18046
18047        synchronized (this) {
18048            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18049                    != PackageManager.PERMISSION_GRANTED) {
18050                throw new SecurityException("Requires permission "
18051                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18052            }
18053
18054            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18055                ProcessRecord r = mLruProcesses.get(i);
18056                if (r.thread != null && r.persistent) {
18057                    Process.sendSignal(r.pid, sig);
18058                }
18059            }
18060        }
18061    }
18062
18063    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18064        if (proc == null || proc == mProfileProc) {
18065            proc = mProfileProc;
18066            profileType = mProfileType;
18067            clearProfilerLocked();
18068        }
18069        if (proc == null) {
18070            return;
18071        }
18072        try {
18073            proc.thread.profilerControl(false, null, profileType);
18074        } catch (RemoteException e) {
18075            throw new IllegalStateException("Process disappeared");
18076        }
18077    }
18078
18079    private void clearProfilerLocked() {
18080        if (mProfileFd != null) {
18081            try {
18082                mProfileFd.close();
18083            } catch (IOException e) {
18084            }
18085        }
18086        mProfileApp = null;
18087        mProfileProc = null;
18088        mProfileFile = null;
18089        mProfileType = 0;
18090        mAutoStopProfiler = false;
18091        mSamplingInterval = 0;
18092    }
18093
18094    public boolean profileControl(String process, int userId, boolean start,
18095            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18096
18097        try {
18098            synchronized (this) {
18099                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18100                // its own permission.
18101                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18102                        != PackageManager.PERMISSION_GRANTED) {
18103                    throw new SecurityException("Requires permission "
18104                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18105                }
18106
18107                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18108                    throw new IllegalArgumentException("null profile info or fd");
18109                }
18110
18111                ProcessRecord proc = null;
18112                if (process != null) {
18113                    proc = findProcessLocked(process, userId, "profileControl");
18114                }
18115
18116                if (start && (proc == null || proc.thread == null)) {
18117                    throw new IllegalArgumentException("Unknown process: " + process);
18118                }
18119
18120                if (start) {
18121                    stopProfilerLocked(null, 0);
18122                    setProfileApp(proc.info, proc.processName, profilerInfo);
18123                    mProfileProc = proc;
18124                    mProfileType = profileType;
18125                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18126                    try {
18127                        fd = fd.dup();
18128                    } catch (IOException e) {
18129                        fd = null;
18130                    }
18131                    profilerInfo.profileFd = fd;
18132                    proc.thread.profilerControl(start, profilerInfo, profileType);
18133                    fd = null;
18134                    mProfileFd = null;
18135                } else {
18136                    stopProfilerLocked(proc, profileType);
18137                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18138                        try {
18139                            profilerInfo.profileFd.close();
18140                        } catch (IOException e) {
18141                        }
18142                    }
18143                }
18144
18145                return true;
18146            }
18147        } catch (RemoteException e) {
18148            throw new IllegalStateException("Process disappeared");
18149        } finally {
18150            if (profilerInfo != null && profilerInfo.profileFd != null) {
18151                try {
18152                    profilerInfo.profileFd.close();
18153                } catch (IOException e) {
18154                }
18155            }
18156        }
18157    }
18158
18159    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18160        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18161                userId, true, ALLOW_FULL_ONLY, callName, null);
18162        ProcessRecord proc = null;
18163        try {
18164            int pid = Integer.parseInt(process);
18165            synchronized (mPidsSelfLocked) {
18166                proc = mPidsSelfLocked.get(pid);
18167            }
18168        } catch (NumberFormatException e) {
18169        }
18170
18171        if (proc == null) {
18172            ArrayMap<String, SparseArray<ProcessRecord>> all
18173                    = mProcessNames.getMap();
18174            SparseArray<ProcessRecord> procs = all.get(process);
18175            if (procs != null && procs.size() > 0) {
18176                proc = procs.valueAt(0);
18177                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18178                    for (int i=1; i<procs.size(); i++) {
18179                        ProcessRecord thisProc = procs.valueAt(i);
18180                        if (thisProc.userId == userId) {
18181                            proc = thisProc;
18182                            break;
18183                        }
18184                    }
18185                }
18186            }
18187        }
18188
18189        return proc;
18190    }
18191
18192    public boolean dumpHeap(String process, int userId, boolean managed,
18193            String path, ParcelFileDescriptor fd) throws RemoteException {
18194
18195        try {
18196            synchronized (this) {
18197                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18198                // its own permission (same as profileControl).
18199                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18200                        != PackageManager.PERMISSION_GRANTED) {
18201                    throw new SecurityException("Requires permission "
18202                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18203                }
18204
18205                if (fd == null) {
18206                    throw new IllegalArgumentException("null fd");
18207                }
18208
18209                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18210                if (proc == null || proc.thread == null) {
18211                    throw new IllegalArgumentException("Unknown process: " + process);
18212                }
18213
18214                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18215                if (!isDebuggable) {
18216                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18217                        throw new SecurityException("Process not debuggable: " + proc);
18218                    }
18219                }
18220
18221                proc.thread.dumpHeap(managed, path, fd);
18222                fd = null;
18223                return true;
18224            }
18225        } catch (RemoteException e) {
18226            throw new IllegalStateException("Process disappeared");
18227        } finally {
18228            if (fd != null) {
18229                try {
18230                    fd.close();
18231                } catch (IOException e) {
18232                }
18233            }
18234        }
18235    }
18236
18237    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18238    public void monitor() {
18239        synchronized (this) { }
18240    }
18241
18242    void onCoreSettingsChange(Bundle settings) {
18243        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18244            ProcessRecord processRecord = mLruProcesses.get(i);
18245            try {
18246                if (processRecord.thread != null) {
18247                    processRecord.thread.setCoreSettings(settings);
18248                }
18249            } catch (RemoteException re) {
18250                /* ignore */
18251            }
18252        }
18253    }
18254
18255    // Multi-user methods
18256
18257    /**
18258     * Start user, if its not already running, but don't bring it to foreground.
18259     */
18260    @Override
18261    public boolean startUserInBackground(final int userId) {
18262        return startUser(userId, /* foreground */ false);
18263    }
18264
18265    /**
18266     * Start user, if its not already running, and bring it to foreground.
18267     */
18268    boolean startUserInForeground(final int userId, Dialog dlg) {
18269        boolean result = startUser(userId, /* foreground */ true);
18270        dlg.dismiss();
18271        return result;
18272    }
18273
18274    /**
18275     * Refreshes the list of users related to the current user when either a
18276     * user switch happens or when a new related user is started in the
18277     * background.
18278     */
18279    private void updateCurrentProfileIdsLocked() {
18280        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18281                mCurrentUserId, false /* enabledOnly */);
18282        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18283        for (int i = 0; i < currentProfileIds.length; i++) {
18284            currentProfileIds[i] = profiles.get(i).id;
18285        }
18286        mCurrentProfileIds = currentProfileIds;
18287
18288        synchronized (mUserProfileGroupIdsSelfLocked) {
18289            mUserProfileGroupIdsSelfLocked.clear();
18290            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18291            for (int i = 0; i < users.size(); i++) {
18292                UserInfo user = users.get(i);
18293                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18294                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18295                }
18296            }
18297        }
18298    }
18299
18300    private Set getProfileIdsLocked(int userId) {
18301        Set userIds = new HashSet<Integer>();
18302        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18303                userId, false /* enabledOnly */);
18304        for (UserInfo user : profiles) {
18305            userIds.add(Integer.valueOf(user.id));
18306        }
18307        return userIds;
18308    }
18309
18310    @Override
18311    public boolean switchUser(final int userId) {
18312        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18313        String userName;
18314        synchronized (this) {
18315            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18316            if (userInfo == null) {
18317                Slog.w(TAG, "No user info for user #" + userId);
18318                return false;
18319            }
18320            if (userInfo.isManagedProfile()) {
18321                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18322                return false;
18323            }
18324            userName = userInfo.name;
18325            mTargetUserId = userId;
18326        }
18327        mHandler.removeMessages(START_USER_SWITCH_MSG);
18328        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18329        return true;
18330    }
18331
18332    private void showUserSwitchDialog(int userId, String userName) {
18333        // The dialog will show and then initiate the user switch by calling startUserInForeground
18334        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18335                true /* above system */);
18336        d.show();
18337    }
18338
18339    private boolean startUser(final int userId, final boolean foreground) {
18340        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18341                != PackageManager.PERMISSION_GRANTED) {
18342            String msg = "Permission Denial: switchUser() from pid="
18343                    + Binder.getCallingPid()
18344                    + ", uid=" + Binder.getCallingUid()
18345                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18346            Slog.w(TAG, msg);
18347            throw new SecurityException(msg);
18348        }
18349
18350        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18351
18352        final long ident = Binder.clearCallingIdentity();
18353        try {
18354            synchronized (this) {
18355                final int oldUserId = mCurrentUserId;
18356                if (oldUserId == userId) {
18357                    return true;
18358                }
18359
18360                mStackSupervisor.setLockTaskModeLocked(null, false);
18361
18362                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18363                if (userInfo == null) {
18364                    Slog.w(TAG, "No user info for user #" + userId);
18365                    return false;
18366                }
18367                if (foreground && userInfo.isManagedProfile()) {
18368                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18369                    return false;
18370                }
18371
18372                if (foreground) {
18373                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18374                            R.anim.screen_user_enter);
18375                }
18376
18377                boolean needStart = false;
18378
18379                // If the user we are switching to is not currently started, then
18380                // we need to start it now.
18381                if (mStartedUsers.get(userId) == null) {
18382                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18383                    updateStartedUserArrayLocked();
18384                    needStart = true;
18385                }
18386
18387                final Integer userIdInt = Integer.valueOf(userId);
18388                mUserLru.remove(userIdInt);
18389                mUserLru.add(userIdInt);
18390
18391                if (foreground) {
18392                    mCurrentUserId = userId;
18393                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18394                    updateCurrentProfileIdsLocked();
18395                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18396                    // Once the internal notion of the active user has switched, we lock the device
18397                    // with the option to show the user switcher on the keyguard.
18398                    mWindowManager.lockNow(null);
18399                } else {
18400                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18401                    updateCurrentProfileIdsLocked();
18402                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18403                    mUserLru.remove(currentUserIdInt);
18404                    mUserLru.add(currentUserIdInt);
18405                }
18406
18407                final UserStartedState uss = mStartedUsers.get(userId);
18408
18409                // Make sure user is in the started state.  If it is currently
18410                // stopping, we need to knock that off.
18411                if (uss.mState == UserStartedState.STATE_STOPPING) {
18412                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18413                    // so we can just fairly silently bring the user back from
18414                    // the almost-dead.
18415                    uss.mState = UserStartedState.STATE_RUNNING;
18416                    updateStartedUserArrayLocked();
18417                    needStart = true;
18418                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18419                    // This means ACTION_SHUTDOWN has been sent, so we will
18420                    // need to treat this as a new boot of the user.
18421                    uss.mState = UserStartedState.STATE_BOOTING;
18422                    updateStartedUserArrayLocked();
18423                    needStart = true;
18424                }
18425
18426                if (uss.mState == UserStartedState.STATE_BOOTING) {
18427                    // Booting up a new user, need to tell system services about it.
18428                    // Note that this is on the same handler as scheduling of broadcasts,
18429                    // which is important because it needs to go first.
18430                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18431                }
18432
18433                if (foreground) {
18434                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18435                            oldUserId));
18436                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18437                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18438                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18439                            oldUserId, userId, uss));
18440                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18441                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18442                }
18443
18444                if (needStart) {
18445                    // Send USER_STARTED broadcast
18446                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18447                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18448                            | Intent.FLAG_RECEIVER_FOREGROUND);
18449                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18450                    broadcastIntentLocked(null, null, intent,
18451                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18452                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18453                }
18454
18455                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18456                    if (userId != UserHandle.USER_OWNER) {
18457                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18458                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18459                        broadcastIntentLocked(null, null, intent, null,
18460                                new IIntentReceiver.Stub() {
18461                                    public void performReceive(Intent intent, int resultCode,
18462                                            String data, Bundle extras, boolean ordered,
18463                                            boolean sticky, int sendingUser) {
18464                                        onUserInitialized(uss, foreground, oldUserId, userId);
18465                                    }
18466                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18467                                true, false, MY_PID, Process.SYSTEM_UID,
18468                                userId);
18469                        uss.initializing = true;
18470                    } else {
18471                        getUserManagerLocked().makeInitialized(userInfo.id);
18472                    }
18473                }
18474
18475                if (foreground) {
18476                    if (!uss.initializing) {
18477                        moveUserToForeground(uss, oldUserId, userId);
18478                    }
18479                } else {
18480                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18481                }
18482
18483                if (needStart) {
18484                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18485                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18486                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18487                    broadcastIntentLocked(null, null, intent,
18488                            null, new IIntentReceiver.Stub() {
18489                                @Override
18490                                public void performReceive(Intent intent, int resultCode, String data,
18491                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18492                                        throws RemoteException {
18493                                }
18494                            }, 0, null, null,
18495                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18496                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18497                }
18498            }
18499        } finally {
18500            Binder.restoreCallingIdentity(ident);
18501        }
18502
18503        return true;
18504    }
18505
18506    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18507        long ident = Binder.clearCallingIdentity();
18508        try {
18509            Intent intent;
18510            if (oldUserId >= 0) {
18511                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18512                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18513                int count = profiles.size();
18514                for (int i = 0; i < count; i++) {
18515                    int profileUserId = profiles.get(i).id;
18516                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18517                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18518                            | Intent.FLAG_RECEIVER_FOREGROUND);
18519                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18520                    broadcastIntentLocked(null, null, intent,
18521                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18522                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18523                }
18524            }
18525            if (newUserId >= 0) {
18526                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18527                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18528                int count = profiles.size();
18529                for (int i = 0; i < count; i++) {
18530                    int profileUserId = profiles.get(i).id;
18531                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18532                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18533                            | Intent.FLAG_RECEIVER_FOREGROUND);
18534                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18535                    broadcastIntentLocked(null, null, intent,
18536                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18537                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18538                }
18539                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18540                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18541                        | Intent.FLAG_RECEIVER_FOREGROUND);
18542                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18543                broadcastIntentLocked(null, null, intent,
18544                        null, null, 0, null, null,
18545                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18546                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18547            }
18548        } finally {
18549            Binder.restoreCallingIdentity(ident);
18550        }
18551    }
18552
18553    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18554            final int newUserId) {
18555        final int N = mUserSwitchObservers.beginBroadcast();
18556        if (N > 0) {
18557            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18558                int mCount = 0;
18559                @Override
18560                public void sendResult(Bundle data) throws RemoteException {
18561                    synchronized (ActivityManagerService.this) {
18562                        if (mCurUserSwitchCallback == this) {
18563                            mCount++;
18564                            if (mCount == N) {
18565                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18566                            }
18567                        }
18568                    }
18569                }
18570            };
18571            synchronized (this) {
18572                uss.switching = true;
18573                mCurUserSwitchCallback = callback;
18574            }
18575            for (int i=0; i<N; i++) {
18576                try {
18577                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18578                            newUserId, callback);
18579                } catch (RemoteException e) {
18580                }
18581            }
18582        } else {
18583            synchronized (this) {
18584                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18585            }
18586        }
18587        mUserSwitchObservers.finishBroadcast();
18588    }
18589
18590    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18591        synchronized (this) {
18592            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18593            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18594        }
18595    }
18596
18597    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18598        mCurUserSwitchCallback = null;
18599        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18600        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18601                oldUserId, newUserId, uss));
18602    }
18603
18604    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18605        synchronized (this) {
18606            if (foreground) {
18607                moveUserToForeground(uss, oldUserId, newUserId);
18608            }
18609        }
18610
18611        completeSwitchAndInitalize(uss, newUserId, true, false);
18612    }
18613
18614    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18615        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18616        if (homeInFront) {
18617            startHomeActivityLocked(newUserId);
18618        } else {
18619            mStackSupervisor.resumeTopActivitiesLocked();
18620        }
18621        EventLogTags.writeAmSwitchUser(newUserId);
18622        getUserManagerLocked().userForeground(newUserId);
18623        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18624    }
18625
18626    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18627        completeSwitchAndInitalize(uss, newUserId, false, true);
18628    }
18629
18630    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18631            boolean clearInitializing, boolean clearSwitching) {
18632        boolean unfrozen = false;
18633        synchronized (this) {
18634            if (clearInitializing) {
18635                uss.initializing = false;
18636                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18637            }
18638            if (clearSwitching) {
18639                uss.switching = false;
18640            }
18641            if (!uss.switching && !uss.initializing) {
18642                mWindowManager.stopFreezingScreen();
18643                unfrozen = true;
18644            }
18645        }
18646        if (unfrozen) {
18647            final int N = mUserSwitchObservers.beginBroadcast();
18648            for (int i=0; i<N; i++) {
18649                try {
18650                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18651                } catch (RemoteException e) {
18652                }
18653            }
18654            mUserSwitchObservers.finishBroadcast();
18655        }
18656    }
18657
18658    void scheduleStartProfilesLocked() {
18659        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18660            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18661                    DateUtils.SECOND_IN_MILLIS);
18662        }
18663    }
18664
18665    void startProfilesLocked() {
18666        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18667        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18668                mCurrentUserId, false /* enabledOnly */);
18669        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18670        for (UserInfo user : profiles) {
18671            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18672                    && user.id != mCurrentUserId) {
18673                toStart.add(user);
18674            }
18675        }
18676        final int n = toStart.size();
18677        int i = 0;
18678        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18679            startUserInBackground(toStart.get(i).id);
18680        }
18681        if (i < n) {
18682            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18683        }
18684    }
18685
18686    void finishUserBoot(UserStartedState uss) {
18687        synchronized (this) {
18688            if (uss.mState == UserStartedState.STATE_BOOTING
18689                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18690                uss.mState = UserStartedState.STATE_RUNNING;
18691                final int userId = uss.mHandle.getIdentifier();
18692                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18693                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18694                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18695                broadcastIntentLocked(null, null, intent,
18696                        null, null, 0, null, null,
18697                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18698                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18699            }
18700        }
18701    }
18702
18703    void finishUserSwitch(UserStartedState uss) {
18704        synchronized (this) {
18705            finishUserBoot(uss);
18706
18707            startProfilesLocked();
18708
18709            int num = mUserLru.size();
18710            int i = 0;
18711            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18712                Integer oldUserId = mUserLru.get(i);
18713                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18714                if (oldUss == null) {
18715                    // Shouldn't happen, but be sane if it does.
18716                    mUserLru.remove(i);
18717                    num--;
18718                    continue;
18719                }
18720                if (oldUss.mState == UserStartedState.STATE_STOPPING
18721                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18722                    // This user is already stopping, doesn't count.
18723                    num--;
18724                    i++;
18725                    continue;
18726                }
18727                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18728                    // Owner and current can't be stopped, but count as running.
18729                    i++;
18730                    continue;
18731                }
18732                // This is a user to be stopped.
18733                stopUserLocked(oldUserId, null);
18734                num--;
18735                i++;
18736            }
18737        }
18738    }
18739
18740    @Override
18741    public int stopUser(final int userId, final IStopUserCallback callback) {
18742        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18743                != PackageManager.PERMISSION_GRANTED) {
18744            String msg = "Permission Denial: switchUser() from pid="
18745                    + Binder.getCallingPid()
18746                    + ", uid=" + Binder.getCallingUid()
18747                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18748            Slog.w(TAG, msg);
18749            throw new SecurityException(msg);
18750        }
18751        if (userId <= 0) {
18752            throw new IllegalArgumentException("Can't stop primary user " + userId);
18753        }
18754        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18755        synchronized (this) {
18756            return stopUserLocked(userId, callback);
18757        }
18758    }
18759
18760    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18761        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18762        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18763            return ActivityManager.USER_OP_IS_CURRENT;
18764        }
18765
18766        final UserStartedState uss = mStartedUsers.get(userId);
18767        if (uss == null) {
18768            // User is not started, nothing to do...  but we do need to
18769            // callback if requested.
18770            if (callback != null) {
18771                mHandler.post(new Runnable() {
18772                    @Override
18773                    public void run() {
18774                        try {
18775                            callback.userStopped(userId);
18776                        } catch (RemoteException e) {
18777                        }
18778                    }
18779                });
18780            }
18781            return ActivityManager.USER_OP_SUCCESS;
18782        }
18783
18784        if (callback != null) {
18785            uss.mStopCallbacks.add(callback);
18786        }
18787
18788        if (uss.mState != UserStartedState.STATE_STOPPING
18789                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18790            uss.mState = UserStartedState.STATE_STOPPING;
18791            updateStartedUserArrayLocked();
18792
18793            long ident = Binder.clearCallingIdentity();
18794            try {
18795                // We are going to broadcast ACTION_USER_STOPPING and then
18796                // once that is done send a final ACTION_SHUTDOWN and then
18797                // stop the user.
18798                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18799                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18800                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18801                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18802                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18803                // This is the result receiver for the final shutdown broadcast.
18804                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18805                    @Override
18806                    public void performReceive(Intent intent, int resultCode, String data,
18807                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18808                        finishUserStop(uss);
18809                    }
18810                };
18811                // This is the result receiver for the initial stopping broadcast.
18812                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18813                    @Override
18814                    public void performReceive(Intent intent, int resultCode, String data,
18815                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18816                        // On to the next.
18817                        synchronized (ActivityManagerService.this) {
18818                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18819                                // Whoops, we are being started back up.  Abort, abort!
18820                                return;
18821                            }
18822                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18823                        }
18824                        mBatteryStatsService.noteEvent(
18825                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18826                                Integer.toString(userId), userId);
18827                        mSystemServiceManager.stopUser(userId);
18828                        broadcastIntentLocked(null, null, shutdownIntent,
18829                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18830                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18831                    }
18832                };
18833                // Kick things off.
18834                broadcastIntentLocked(null, null, stoppingIntent,
18835                        null, stoppingReceiver, 0, null, null,
18836                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18837                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18838            } finally {
18839                Binder.restoreCallingIdentity(ident);
18840            }
18841        }
18842
18843        return ActivityManager.USER_OP_SUCCESS;
18844    }
18845
18846    void finishUserStop(UserStartedState uss) {
18847        final int userId = uss.mHandle.getIdentifier();
18848        boolean stopped;
18849        ArrayList<IStopUserCallback> callbacks;
18850        synchronized (this) {
18851            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18852            if (mStartedUsers.get(userId) != uss) {
18853                stopped = false;
18854            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18855                stopped = false;
18856            } else {
18857                stopped = true;
18858                // User can no longer run.
18859                mStartedUsers.remove(userId);
18860                mUserLru.remove(Integer.valueOf(userId));
18861                updateStartedUserArrayLocked();
18862
18863                // Clean up all state and processes associated with the user.
18864                // Kill all the processes for the user.
18865                forceStopUserLocked(userId, "finish user");
18866            }
18867
18868            // Explicitly remove the old information in mRecentTasks.
18869            removeRecentTasksForUserLocked(userId);
18870        }
18871
18872        for (int i=0; i<callbacks.size(); i++) {
18873            try {
18874                if (stopped) callbacks.get(i).userStopped(userId);
18875                else callbacks.get(i).userStopAborted(userId);
18876            } catch (RemoteException e) {
18877            }
18878        }
18879
18880        if (stopped) {
18881            mSystemServiceManager.cleanupUser(userId);
18882            synchronized (this) {
18883                mStackSupervisor.removeUserLocked(userId);
18884            }
18885        }
18886    }
18887
18888    @Override
18889    public UserInfo getCurrentUser() {
18890        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18891                != PackageManager.PERMISSION_GRANTED) && (
18892                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18893                != PackageManager.PERMISSION_GRANTED)) {
18894            String msg = "Permission Denial: getCurrentUser() from pid="
18895                    + Binder.getCallingPid()
18896                    + ", uid=" + Binder.getCallingUid()
18897                    + " requires " + INTERACT_ACROSS_USERS;
18898            Slog.w(TAG, msg);
18899            throw new SecurityException(msg);
18900        }
18901        synchronized (this) {
18902            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18903            return getUserManagerLocked().getUserInfo(userId);
18904        }
18905    }
18906
18907    int getCurrentUserIdLocked() {
18908        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18909    }
18910
18911    @Override
18912    public boolean isUserRunning(int userId, boolean orStopped) {
18913        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18914                != PackageManager.PERMISSION_GRANTED) {
18915            String msg = "Permission Denial: isUserRunning() from pid="
18916                    + Binder.getCallingPid()
18917                    + ", uid=" + Binder.getCallingUid()
18918                    + " requires " + INTERACT_ACROSS_USERS;
18919            Slog.w(TAG, msg);
18920            throw new SecurityException(msg);
18921        }
18922        synchronized (this) {
18923            return isUserRunningLocked(userId, orStopped);
18924        }
18925    }
18926
18927    boolean isUserRunningLocked(int userId, boolean orStopped) {
18928        UserStartedState state = mStartedUsers.get(userId);
18929        if (state == null) {
18930            return false;
18931        }
18932        if (orStopped) {
18933            return true;
18934        }
18935        return state.mState != UserStartedState.STATE_STOPPING
18936                && state.mState != UserStartedState.STATE_SHUTDOWN;
18937    }
18938
18939    @Override
18940    public int[] getRunningUserIds() {
18941        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18942                != PackageManager.PERMISSION_GRANTED) {
18943            String msg = "Permission Denial: isUserRunning() from pid="
18944                    + Binder.getCallingPid()
18945                    + ", uid=" + Binder.getCallingUid()
18946                    + " requires " + INTERACT_ACROSS_USERS;
18947            Slog.w(TAG, msg);
18948            throw new SecurityException(msg);
18949        }
18950        synchronized (this) {
18951            return mStartedUserArray;
18952        }
18953    }
18954
18955    private void updateStartedUserArrayLocked() {
18956        int num = 0;
18957        for (int i=0; i<mStartedUsers.size();  i++) {
18958            UserStartedState uss = mStartedUsers.valueAt(i);
18959            // This list does not include stopping users.
18960            if (uss.mState != UserStartedState.STATE_STOPPING
18961                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18962                num++;
18963            }
18964        }
18965        mStartedUserArray = new int[num];
18966        num = 0;
18967        for (int i=0; i<mStartedUsers.size();  i++) {
18968            UserStartedState uss = mStartedUsers.valueAt(i);
18969            if (uss.mState != UserStartedState.STATE_STOPPING
18970                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18971                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18972                num++;
18973            }
18974        }
18975    }
18976
18977    @Override
18978    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18979        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18980                != PackageManager.PERMISSION_GRANTED) {
18981            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18982                    + Binder.getCallingPid()
18983                    + ", uid=" + Binder.getCallingUid()
18984                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18985            Slog.w(TAG, msg);
18986            throw new SecurityException(msg);
18987        }
18988
18989        mUserSwitchObservers.register(observer);
18990    }
18991
18992    @Override
18993    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18994        mUserSwitchObservers.unregister(observer);
18995    }
18996
18997    private boolean userExists(int userId) {
18998        if (userId == 0) {
18999            return true;
19000        }
19001        UserManagerService ums = getUserManagerLocked();
19002        return ums != null ? (ums.getUserInfo(userId) != null) : false;
19003    }
19004
19005    int[] getUsersLocked() {
19006        UserManagerService ums = getUserManagerLocked();
19007        return ums != null ? ums.getUserIds() : new int[] { 0 };
19008    }
19009
19010    UserManagerService getUserManagerLocked() {
19011        if (mUserManager == null) {
19012            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19013            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19014        }
19015        return mUserManager;
19016    }
19017
19018    private int applyUserId(int uid, int userId) {
19019        return UserHandle.getUid(userId, uid);
19020    }
19021
19022    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19023        if (info == null) return null;
19024        ApplicationInfo newInfo = new ApplicationInfo(info);
19025        newInfo.uid = applyUserId(info.uid, userId);
19026        newInfo.dataDir = USER_DATA_DIR + userId + "/"
19027                + info.packageName;
19028        return newInfo;
19029    }
19030
19031    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19032        if (aInfo == null
19033                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19034            return aInfo;
19035        }
19036
19037        ActivityInfo info = new ActivityInfo(aInfo);
19038        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19039        return info;
19040    }
19041
19042    private final class LocalService extends ActivityManagerInternal {
19043        @Override
19044        public void goingToSleep() {
19045            ActivityManagerService.this.goingToSleep();
19046        }
19047
19048        @Override
19049        public void wakingUp() {
19050            ActivityManagerService.this.wakingUp();
19051        }
19052
19053        @Override
19054        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19055                String processName, String abiOverride, int uid, Runnable crashHandler) {
19056            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19057                    processName, abiOverride, uid, crashHandler);
19058        }
19059    }
19060
19061    /**
19062     * An implementation of IAppTask, that allows an app to manage its own tasks via
19063     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
19064     * only the process that calls getAppTasks() can call the AppTask methods.
19065     */
19066    class AppTaskImpl extends IAppTask.Stub {
19067        private int mTaskId;
19068        private int mCallingUid;
19069
19070        public AppTaskImpl(int taskId, int callingUid) {
19071            mTaskId = taskId;
19072            mCallingUid = callingUid;
19073        }
19074
19075        private void checkCaller() {
19076            if (mCallingUid != Binder.getCallingUid()) {
19077                throw new SecurityException("Caller " + mCallingUid
19078                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19079            }
19080        }
19081
19082        @Override
19083        public void finishAndRemoveTask() {
19084            checkCaller();
19085
19086            synchronized (ActivityManagerService.this) {
19087                long origId = Binder.clearCallingIdentity();
19088                try {
19089                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19090                    if (tr == null) {
19091                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19092                    }
19093                    // Only kill the process if we are not a new document
19094                    int flags = tr.getBaseIntent().getFlags();
19095                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19096                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19097                    removeTaskByIdLocked(mTaskId,
19098                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19099                } finally {
19100                    Binder.restoreCallingIdentity(origId);
19101                }
19102            }
19103        }
19104
19105        @Override
19106        public ActivityManager.RecentTaskInfo getTaskInfo() {
19107            checkCaller();
19108
19109            synchronized (ActivityManagerService.this) {
19110                long origId = Binder.clearCallingIdentity();
19111                try {
19112                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19113                    if (tr == null) {
19114                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19115                    }
19116                    return createRecentTaskInfoFromTaskRecord(tr);
19117                } finally {
19118                    Binder.restoreCallingIdentity(origId);
19119                }
19120            }
19121        }
19122
19123        @Override
19124        public void moveToFront() {
19125            checkCaller();
19126
19127            final TaskRecord tr;
19128            synchronized (ActivityManagerService.this) {
19129                tr = recentTaskForIdLocked(mTaskId);
19130                if (tr == null) {
19131                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19132                }
19133                if (tr.getRootActivity() != null) {
19134                    moveTaskToFrontLocked(tr.taskId, 0, null);
19135                    return;
19136                }
19137            }
19138
19139            startActivityFromRecentsInner(tr.taskId, null);
19140        }
19141
19142        @Override
19143        public int startActivity(IBinder whoThread, String callingPackage,
19144                Intent intent, String resolvedType, Bundle options) {
19145            checkCaller();
19146
19147            int callingUser = UserHandle.getCallingUserId();
19148            TaskRecord tr;
19149            IApplicationThread appThread;
19150            synchronized (ActivityManagerService.this) {
19151                tr = recentTaskForIdLocked(mTaskId);
19152                if (tr == null) {
19153                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19154                }
19155                appThread = ApplicationThreadNative.asInterface(whoThread);
19156                if (appThread == null) {
19157                    throw new IllegalArgumentException("Bad app thread " + appThread);
19158                }
19159            }
19160            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19161                    resolvedType, null, null, null, null, 0, 0, null, null,
19162                    null, options, callingUser, null, tr);
19163        }
19164
19165        @Override
19166        public void setExcludeFromRecents(boolean exclude) {
19167            checkCaller();
19168
19169            synchronized (ActivityManagerService.this) {
19170                long origId = Binder.clearCallingIdentity();
19171                try {
19172                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19173                    if (tr == null) {
19174                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19175                    }
19176                    Intent intent = tr.getBaseIntent();
19177                    if (exclude) {
19178                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19179                    } else {
19180                        intent.setFlags(intent.getFlags()
19181                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19182                    }
19183                } finally {
19184                    Binder.restoreCallingIdentity(origId);
19185                }
19186            }
19187        }
19188    }
19189}
19190