ActivityManagerService.java revision 8d05172112436a81bed6e4a0810f8914509d8a4d
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 boolean haveResult = false;
438        public Bundle result = null;
439        public PendingAssistExtras(ActivityRecord _activity) {
440            activity = _activity;
441        }
442        @Override
443        public void run() {
444            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
445            synchronized (this) {
446                haveResult = true;
447                notifyAll();
448            }
449        }
450    }
451
452    final ArrayList<PendingAssistExtras> mPendingAssistExtras
453            = new ArrayList<PendingAssistExtras>();
454
455    /**
456     * Process management.
457     */
458    final ProcessList mProcessList = new ProcessList();
459
460    /**
461     * All of the applications we currently have running organized by name.
462     * The keys are strings of the application package name (as
463     * returned by the package manager), and the keys are ApplicationRecord
464     * objects.
465     */
466    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
467
468    /**
469     * Tracking long-term execution of processes to look for abuse and other
470     * bad app behavior.
471     */
472    final ProcessStatsService mProcessStats;
473
474    /**
475     * The currently running isolated processes.
476     */
477    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
478
479    /**
480     * Counter for assigning isolated process uids, to avoid frequently reusing the
481     * same ones.
482     */
483    int mNextIsolatedProcessUid = 0;
484
485    /**
486     * The currently running heavy-weight process, if any.
487     */
488    ProcessRecord mHeavyWeightProcess = null;
489
490    /**
491     * The last time that various processes have crashed.
492     */
493    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
494
495    /**
496     * Information about a process that is currently marked as bad.
497     */
498    static final class BadProcessInfo {
499        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
500            this.time = time;
501            this.shortMsg = shortMsg;
502            this.longMsg = longMsg;
503            this.stack = stack;
504        }
505
506        final long time;
507        final String shortMsg;
508        final String longMsg;
509        final String stack;
510    }
511
512    /**
513     * Set of applications that we consider to be bad, and will reject
514     * incoming broadcasts from (which the user has no control over).
515     * Processes are added to this set when they have crashed twice within
516     * a minimum amount of time; they are removed from it when they are
517     * later restarted (hopefully due to some user action).  The value is the
518     * time it was added to the list.
519     */
520    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
521
522    /**
523     * All of the processes we currently have running organized by pid.
524     * The keys are the pid running the application.
525     *
526     * <p>NOTE: This object is protected by its own lock, NOT the global
527     * activity manager lock!
528     */
529    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
530
531    /**
532     * All of the processes that have been forced to be foreground.  The key
533     * is the pid of the caller who requested it (we hold a death
534     * link on it).
535     */
536    abstract class ForegroundToken implements IBinder.DeathRecipient {
537        int pid;
538        IBinder token;
539    }
540    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
541
542    /**
543     * List of records for processes that someone had tried to start before the
544     * system was ready.  We don't start them at that point, but ensure they
545     * are started by the time booting is complete.
546     */
547    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
548
549    /**
550     * List of persistent applications that are in the process
551     * of being started.
552     */
553    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
554
555    /**
556     * Processes that are being forcibly torn down.
557     */
558    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
559
560    /**
561     * List of running applications, sorted by recent usage.
562     * The first entry in the list is the least recently used.
563     */
564    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
565
566    /**
567     * Where in mLruProcesses that the processes hosting activities start.
568     */
569    int mLruProcessActivityStart = 0;
570
571    /**
572     * Where in mLruProcesses that the processes hosting services start.
573     * This is after (lower index) than mLruProcessesActivityStart.
574     */
575    int mLruProcessServiceStart = 0;
576
577    /**
578     * List of processes that should gc as soon as things are idle.
579     */
580    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
581
582    /**
583     * Processes we want to collect PSS data from.
584     */
585    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
586
587    /**
588     * Last time we requested PSS data of all processes.
589     */
590    long mLastFullPssTime = SystemClock.uptimeMillis();
591
592    /**
593     * If set, the next time we collect PSS data we should do a full collection
594     * with data from native processes and the kernel.
595     */
596    boolean mFullPssPending = false;
597
598    /**
599     * This is the process holding what we currently consider to be
600     * the "home" activity.
601     */
602    ProcessRecord mHomeProcess;
603
604    /**
605     * This is the process holding the activity the user last visited that
606     * is in a different process from the one they are currently in.
607     */
608    ProcessRecord mPreviousProcess;
609
610    /**
611     * The time at which the previous process was last visible.
612     */
613    long mPreviousProcessVisibleTime;
614
615    /**
616     * Which uses have been started, so are allowed to run code.
617     */
618    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
619
620    /**
621     * LRU list of history of current users.  Most recently current is at the end.
622     */
623    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
624
625    /**
626     * Constant array of the users that are currently started.
627     */
628    int[] mStartedUserArray = new int[] { 0 };
629
630    /**
631     * Registered observers of the user switching mechanics.
632     */
633    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
634            = new RemoteCallbackList<IUserSwitchObserver>();
635
636    /**
637     * Currently active user switch.
638     */
639    Object mCurUserSwitchCallback;
640
641    /**
642     * Packages that the user has asked to have run in screen size
643     * compatibility mode instead of filling the screen.
644     */
645    final CompatModePackages mCompatModePackages;
646
647    /**
648     * Set of IntentSenderRecord objects that are currently active.
649     */
650    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
651            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
652
653    /**
654     * Fingerprints (hashCode()) of stack traces that we've
655     * already logged DropBox entries for.  Guarded by itself.  If
656     * something (rogue user app) forces this over
657     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
658     */
659    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
660    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
661
662    /**
663     * Strict Mode background batched logging state.
664     *
665     * The string buffer is guarded by itself, and its lock is also
666     * used to determine if another batched write is already
667     * in-flight.
668     */
669    private final StringBuilder mStrictModeBuffer = new StringBuilder();
670
671    /**
672     * Keeps track of all IIntentReceivers that have been registered for
673     * broadcasts.  Hash keys are the receiver IBinder, hash value is
674     * a ReceiverList.
675     */
676    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
677            new HashMap<IBinder, ReceiverList>();
678
679    /**
680     * Resolver for broadcast intents to registered receivers.
681     * Holds BroadcastFilter (subclass of IntentFilter).
682     */
683    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
684            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
685        @Override
686        protected boolean allowFilterResult(
687                BroadcastFilter filter, List<BroadcastFilter> dest) {
688            IBinder target = filter.receiverList.receiver.asBinder();
689            for (int i=dest.size()-1; i>=0; i--) {
690                if (dest.get(i).receiverList.receiver.asBinder() == target) {
691                    return false;
692                }
693            }
694            return true;
695        }
696
697        @Override
698        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
699            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
700                    || userId == filter.owningUserId) {
701                return super.newResult(filter, match, userId);
702            }
703            return null;
704        }
705
706        @Override
707        protected BroadcastFilter[] newArray(int size) {
708            return new BroadcastFilter[size];
709        }
710
711        @Override
712        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
713            return packageName.equals(filter.packageName);
714        }
715    };
716
717    /**
718     * State of all active sticky broadcasts per user.  Keys are the action of the
719     * sticky Intent, values are an ArrayList of all broadcasted intents with
720     * that action (which should usually be one).  The SparseArray is keyed
721     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
722     * for stickies that are sent to all users.
723     */
724    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
725            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
726
727    final ActiveServices mServices;
728
729    /**
730     * Backup/restore process management
731     */
732    String mBackupAppName = null;
733    BackupRecord mBackupTarget = null;
734
735    final ProviderMap mProviderMap;
736
737    /**
738     * List of content providers who have clients waiting for them.  The
739     * application is currently being launched and the provider will be
740     * removed from this list once it is published.
741     */
742    final ArrayList<ContentProviderRecord> mLaunchingProviders
743            = new ArrayList<ContentProviderRecord>();
744
745    /**
746     * File storing persisted {@link #mGrantedUriPermissions}.
747     */
748    private final AtomicFile mGrantFile;
749
750    /** XML constants used in {@link #mGrantFile} */
751    private static final String TAG_URI_GRANTS = "uri-grants";
752    private static final String TAG_URI_GRANT = "uri-grant";
753    private static final String ATTR_USER_HANDLE = "userHandle";
754    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
755    private static final String ATTR_TARGET_USER_ID = "targetUserId";
756    private static final String ATTR_SOURCE_PKG = "sourcePkg";
757    private static final String ATTR_TARGET_PKG = "targetPkg";
758    private static final String ATTR_URI = "uri";
759    private static final String ATTR_MODE_FLAGS = "modeFlags";
760    private static final String ATTR_CREATED_TIME = "createdTime";
761    private static final String ATTR_PREFIX = "prefix";
762
763    /**
764     * Global set of specific {@link Uri} permissions that have been granted.
765     * This optimized lookup structure maps from {@link UriPermission#targetUid}
766     * to {@link UriPermission#uri} to {@link UriPermission}.
767     */
768    @GuardedBy("this")
769    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
770            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
771
772    public static class GrantUri {
773        public final int sourceUserId;
774        public final Uri uri;
775        public boolean prefix;
776
777        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
778            this.sourceUserId = sourceUserId;
779            this.uri = uri;
780            this.prefix = prefix;
781        }
782
783        @Override
784        public int hashCode() {
785            return toString().hashCode();
786        }
787
788        @Override
789        public boolean equals(Object o) {
790            if (o instanceof GrantUri) {
791                GrantUri other = (GrantUri) o;
792                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
793                        && prefix == other.prefix;
794            }
795            return false;
796        }
797
798        @Override
799        public String toString() {
800            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
801            if (prefix) result += " [prefix]";
802            return result;
803        }
804
805        public String toSafeString() {
806            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
807            if (prefix) result += " [prefix]";
808            return result;
809        }
810
811        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
812            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
813                    ContentProvider.getUriWithoutUserId(uri), false);
814        }
815    }
816
817    CoreSettingsObserver mCoreSettingsObserver;
818
819    /**
820     * Thread-local storage used to carry caller permissions over through
821     * indirect content-provider access.
822     */
823    private class Identity {
824        public int pid;
825        public int uid;
826
827        Identity(int _pid, int _uid) {
828            pid = _pid;
829            uid = _uid;
830        }
831    }
832
833    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
834
835    /**
836     * All information we have collected about the runtime performance of
837     * any user id that can impact battery performance.
838     */
839    final BatteryStatsService mBatteryStatsService;
840
841    /**
842     * Information about component usage
843     */
844    UsageStatsManagerInternal mUsageStatsService;
845
846    /**
847     * Information about and control over application operations
848     */
849    final AppOpsService mAppOpsService;
850
851    /**
852     * Save recent tasks information across reboots.
853     */
854    final TaskPersister mTaskPersister;
855
856    /**
857     * Current configuration information.  HistoryRecord objects are given
858     * a reference to this object to indicate which configuration they are
859     * currently running in, so this object must be kept immutable.
860     */
861    Configuration mConfiguration = new Configuration();
862
863    /**
864     * Current sequencing integer of the configuration, for skipping old
865     * configurations.
866     */
867    int mConfigurationSeq = 0;
868
869    /**
870     * Hardware-reported OpenGLES version.
871     */
872    final int GL_ES_VERSION;
873
874    /**
875     * List of initialization arguments to pass to all processes when binding applications to them.
876     * For example, references to the commonly used services.
877     */
878    HashMap<String, IBinder> mAppBindArgs;
879
880    /**
881     * Temporary to avoid allocations.  Protected by main lock.
882     */
883    final StringBuilder mStringBuilder = new StringBuilder(256);
884
885    /**
886     * Used to control how we initialize the service.
887     */
888    ComponentName mTopComponent;
889    String mTopAction = Intent.ACTION_MAIN;
890    String mTopData;
891    boolean mProcessesReady = false;
892    boolean mSystemReady = false;
893    boolean mBooting = false;
894    boolean mCallFinishBooting = false;
895    boolean mBootAnimationComplete = false;
896    boolean mWaitingUpdate = false;
897    boolean mDidUpdate = false;
898    boolean mOnBattery = false;
899    boolean mLaunchWarningShown = false;
900
901    Context mContext;
902
903    int mFactoryTest;
904
905    boolean mCheckedForSetup;
906
907    /**
908     * The time at which we will allow normal application switches again,
909     * after a call to {@link #stopAppSwitches()}.
910     */
911    long mAppSwitchesAllowedTime;
912
913    /**
914     * This is set to true after the first switch after mAppSwitchesAllowedTime
915     * is set; any switches after that will clear the time.
916     */
917    boolean mDidAppSwitch;
918
919    /**
920     * Last time (in realtime) at which we checked for power usage.
921     */
922    long mLastPowerCheckRealtime;
923
924    /**
925     * Last time (in uptime) at which we checked for power usage.
926     */
927    long mLastPowerCheckUptime;
928
929    /**
930     * Set while we are wanting to sleep, to prevent any
931     * activities from being started/resumed.
932     */
933    private boolean mSleeping = false;
934
935    /**
936     * Set while we are running a voice interaction.  This overrides
937     * sleeping while it is active.
938     */
939    private boolean mRunningVoice = false;
940
941    /**
942     * State of external calls telling us if the device is asleep.
943     */
944    private boolean mWentToSleep = false;
945
946    /**
947     * State of external call telling us if the lock screen is shown.
948     */
949    private boolean mLockScreenShown = false;
950
951    /**
952     * Set if we are shutting down the system, similar to sleeping.
953     */
954    boolean mShuttingDown = false;
955
956    /**
957     * Current sequence id for oom_adj computation traversal.
958     */
959    int mAdjSeq = 0;
960
961    /**
962     * Current sequence id for process LRU updating.
963     */
964    int mLruSeq = 0;
965
966    /**
967     * Keep track of the non-cached/empty process we last found, to help
968     * determine how to distribute cached/empty processes next time.
969     */
970    int mNumNonCachedProcs = 0;
971
972    /**
973     * Keep track of the number of cached hidden procs, to balance oom adj
974     * distribution between those and empty procs.
975     */
976    int mNumCachedHiddenProcs = 0;
977
978    /**
979     * Keep track of the number of service processes we last found, to
980     * determine on the next iteration which should be B services.
981     */
982    int mNumServiceProcs = 0;
983    int mNewNumAServiceProcs = 0;
984    int mNewNumServiceProcs = 0;
985
986    /**
987     * Allow the current computed overall memory level of the system to go down?
988     * This is set to false when we are killing processes for reasons other than
989     * memory management, so that the now smaller process list will not be taken as
990     * an indication that memory is tighter.
991     */
992    boolean mAllowLowerMemLevel = false;
993
994    /**
995     * The last computed memory level, for holding when we are in a state that
996     * processes are going away for other reasons.
997     */
998    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
999
1000    /**
1001     * The last total number of process we have, to determine if changes actually look
1002     * like a shrinking number of process due to lower RAM.
1003     */
1004    int mLastNumProcesses;
1005
1006    /**
1007     * The uptime of the last time we performed idle maintenance.
1008     */
1009    long mLastIdleTime = SystemClock.uptimeMillis();
1010
1011    /**
1012     * Total time spent with RAM that has been added in the past since the last idle time.
1013     */
1014    long mLowRamTimeSinceLastIdle = 0;
1015
1016    /**
1017     * If RAM is currently low, when that horrible situation started.
1018     */
1019    long mLowRamStartTime = 0;
1020
1021    /**
1022     * For reporting to battery stats the current top application.
1023     */
1024    private String mCurResumedPackage = null;
1025    private int mCurResumedUid = -1;
1026
1027    /**
1028     * For reporting to battery stats the apps currently running foreground
1029     * service.  The ProcessMap is package/uid tuples; each of these contain
1030     * an array of the currently foreground processes.
1031     */
1032    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1033            = new ProcessMap<ArrayList<ProcessRecord>>();
1034
1035    /**
1036     * This is set if we had to do a delayed dexopt of an app before launching
1037     * it, to increase the ANR timeouts in that case.
1038     */
1039    boolean mDidDexOpt;
1040
1041    /**
1042     * Set if the systemServer made a call to enterSafeMode.
1043     */
1044    boolean mSafeMode;
1045
1046    String mDebugApp = null;
1047    boolean mWaitForDebugger = false;
1048    boolean mDebugTransient = false;
1049    String mOrigDebugApp = null;
1050    boolean mOrigWaitForDebugger = false;
1051    boolean mAlwaysFinishActivities = false;
1052    IActivityController mController = null;
1053    String mProfileApp = null;
1054    ProcessRecord mProfileProc = null;
1055    String mProfileFile;
1056    ParcelFileDescriptor mProfileFd;
1057    int mSamplingInterval = 0;
1058    boolean mAutoStopProfiler = false;
1059    int mProfileType = 0;
1060    String mOpenGlTraceApp = null;
1061
1062    static class ProcessChangeItem {
1063        static final int CHANGE_ACTIVITIES = 1<<0;
1064        static final int CHANGE_PROCESS_STATE = 1<<1;
1065        int changes;
1066        int uid;
1067        int pid;
1068        int processState;
1069        boolean foregroundActivities;
1070    }
1071
1072    final RemoteCallbackList<IProcessObserver> mProcessObservers
1073            = new RemoteCallbackList<IProcessObserver>();
1074    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1075
1076    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1077            = new ArrayList<ProcessChangeItem>();
1078    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1079            = new ArrayList<ProcessChangeItem>();
1080
1081    /**
1082     * Runtime CPU use collection thread.  This object's lock is used to
1083     * perform synchronization with the thread (notifying it to run).
1084     */
1085    final Thread mProcessCpuThread;
1086
1087    /**
1088     * Used to collect per-process CPU use for ANRs, battery stats, etc.
1089     * Must acquire this object's lock when accessing it.
1090     * NOTE: this lock will be held while doing long operations (trawling
1091     * through all processes in /proc), so it should never be acquired by
1092     * any critical paths such as when holding the main activity manager lock.
1093     */
1094    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1095            MONITOR_THREAD_CPU_USAGE);
1096    final AtomicLong mLastCpuTime = new AtomicLong(0);
1097    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1098
1099    long mLastWriteTime = 0;
1100
1101    /**
1102     * Used to retain an update lock when the foreground activity is in
1103     * immersive mode.
1104     */
1105    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1106
1107    /**
1108     * Set to true after the system has finished booting.
1109     */
1110    boolean mBooted = false;
1111
1112    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1113    int mProcessLimitOverride = -1;
1114
1115    WindowManagerService mWindowManager;
1116
1117    final ActivityThread mSystemThread;
1118
1119    // Holds the current foreground user's id
1120    int mCurrentUserId = 0;
1121    // Holds the target user's id during a user switch
1122    int mTargetUserId = UserHandle.USER_NULL;
1123    // If there are multiple profiles for the current user, their ids are here
1124    // Currently only the primary user can have managed profiles
1125    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1126
1127    /**
1128     * Mapping from each known user ID to the profile group ID it is associated with.
1129     */
1130    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1131
1132    private UserManagerService mUserManager;
1133
1134    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1135        final ProcessRecord mApp;
1136        final int mPid;
1137        final IApplicationThread mAppThread;
1138
1139        AppDeathRecipient(ProcessRecord app, int pid,
1140                IApplicationThread thread) {
1141            if (localLOGV) Slog.v(
1142                TAG, "New death recipient " + this
1143                + " for thread " + thread.asBinder());
1144            mApp = app;
1145            mPid = pid;
1146            mAppThread = thread;
1147        }
1148
1149        @Override
1150        public void binderDied() {
1151            if (localLOGV) Slog.v(
1152                TAG, "Death received in " + this
1153                + " for thread " + mAppThread.asBinder());
1154            synchronized(ActivityManagerService.this) {
1155                appDiedLocked(mApp, mPid, mAppThread);
1156            }
1157        }
1158    }
1159
1160    static final int SHOW_ERROR_MSG = 1;
1161    static final int SHOW_NOT_RESPONDING_MSG = 2;
1162    static final int SHOW_FACTORY_ERROR_MSG = 3;
1163    static final int UPDATE_CONFIGURATION_MSG = 4;
1164    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1165    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1166    static final int SERVICE_TIMEOUT_MSG = 12;
1167    static final int UPDATE_TIME_ZONE = 13;
1168    static final int SHOW_UID_ERROR_MSG = 14;
1169    static final int IM_FEELING_LUCKY_MSG = 15;
1170    static final int PROC_START_TIMEOUT_MSG = 20;
1171    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1172    static final int KILL_APPLICATION_MSG = 22;
1173    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1174    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1175    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1176    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1177    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1178    static final int CLEAR_DNS_CACHE_MSG = 28;
1179    static final int UPDATE_HTTP_PROXY_MSG = 29;
1180    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1181    static final int DISPATCH_PROCESSES_CHANGED = 31;
1182    static final int DISPATCH_PROCESS_DIED = 32;
1183    static final int REPORT_MEM_USAGE_MSG = 33;
1184    static final int REPORT_USER_SWITCH_MSG = 34;
1185    static final int CONTINUE_USER_SWITCH_MSG = 35;
1186    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1187    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1188    static final int PERSIST_URI_GRANTS_MSG = 38;
1189    static final int REQUEST_ALL_PSS_MSG = 39;
1190    static final int START_PROFILES_MSG = 40;
1191    static final int UPDATE_TIME = 41;
1192    static final int SYSTEM_USER_START_MSG = 42;
1193    static final int SYSTEM_USER_CURRENT_MSG = 43;
1194    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1195    static final int FINISH_BOOTING_MSG = 45;
1196    static final int START_USER_SWITCH_MSG = 46;
1197    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1198
1199    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1200    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1201    static final int FIRST_COMPAT_MODE_MSG = 300;
1202    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1203
1204    AlertDialog mUidAlert;
1205    CompatModeDialog mCompatModeDialog;
1206    long mLastMemUsageReportTime = 0;
1207
1208    private LockToAppRequestDialog mLockToAppRequest;
1209
1210    /**
1211     * Flag whether the current user is a "monkey", i.e. whether
1212     * the UI is driven by a UI automation tool.
1213     */
1214    private boolean mUserIsMonkey;
1215
1216    /** Flag whether the device has a Recents UI */
1217    boolean mHasRecents;
1218
1219    /** The dimensions of the thumbnails in the Recents UI. */
1220    int mThumbnailWidth;
1221    int mThumbnailHeight;
1222
1223    final ServiceThread mHandlerThread;
1224    final MainHandler mHandler;
1225
1226    final class MainHandler extends Handler {
1227        public MainHandler(Looper looper) {
1228            super(looper, null, true);
1229        }
1230
1231        @Override
1232        public void handleMessage(Message msg) {
1233            switch (msg.what) {
1234            case SHOW_ERROR_MSG: {
1235                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1236                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1237                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1238                synchronized (ActivityManagerService.this) {
1239                    ProcessRecord proc = (ProcessRecord)data.get("app");
1240                    AppErrorResult res = (AppErrorResult) data.get("result");
1241                    if (proc != null && proc.crashDialog != null) {
1242                        Slog.e(TAG, "App already has crash dialog: " + proc);
1243                        if (res != null) {
1244                            res.set(0);
1245                        }
1246                        return;
1247                    }
1248                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1249                            >= Process.FIRST_APPLICATION_UID
1250                            && proc.pid != MY_PID);
1251                    for (int userId : mCurrentProfileIds) {
1252                        isBackground &= (proc.userId != userId);
1253                    }
1254                    if (isBackground && !showBackground) {
1255                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1256                        if (res != null) {
1257                            res.set(0);
1258                        }
1259                        return;
1260                    }
1261                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1262                        Dialog d = new AppErrorDialog(mContext,
1263                                ActivityManagerService.this, res, proc);
1264                        d.show();
1265                        proc.crashDialog = d;
1266                    } else {
1267                        // The device is asleep, so just pretend that the user
1268                        // saw a crash dialog and hit "force quit".
1269                        if (res != null) {
1270                            res.set(0);
1271                        }
1272                    }
1273                }
1274
1275                ensureBootCompleted();
1276            } break;
1277            case SHOW_NOT_RESPONDING_MSG: {
1278                synchronized (ActivityManagerService.this) {
1279                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1280                    ProcessRecord proc = (ProcessRecord)data.get("app");
1281                    if (proc != null && proc.anrDialog != null) {
1282                        Slog.e(TAG, "App already has anr dialog: " + proc);
1283                        return;
1284                    }
1285
1286                    Intent intent = new Intent("android.intent.action.ANR");
1287                    if (!mProcessesReady) {
1288                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1289                                | Intent.FLAG_RECEIVER_FOREGROUND);
1290                    }
1291                    broadcastIntentLocked(null, null, intent,
1292                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1293                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1294
1295                    if (mShowDialogs) {
1296                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1297                                mContext, proc, (ActivityRecord)data.get("activity"),
1298                                msg.arg1 != 0);
1299                        d.show();
1300                        proc.anrDialog = d;
1301                    } else {
1302                        // Just kill the app if there is no dialog to be shown.
1303                        killAppAtUsersRequest(proc, null);
1304                    }
1305                }
1306
1307                ensureBootCompleted();
1308            } break;
1309            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1310                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1311                synchronized (ActivityManagerService.this) {
1312                    ProcessRecord proc = (ProcessRecord) data.get("app");
1313                    if (proc == null) {
1314                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1315                        break;
1316                    }
1317                    if (proc.crashDialog != null) {
1318                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1319                        return;
1320                    }
1321                    AppErrorResult res = (AppErrorResult) data.get("result");
1322                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1323                        Dialog d = new StrictModeViolationDialog(mContext,
1324                                ActivityManagerService.this, res, proc);
1325                        d.show();
1326                        proc.crashDialog = d;
1327                    } else {
1328                        // The device is asleep, so just pretend that the user
1329                        // saw a crash dialog and hit "force quit".
1330                        res.set(0);
1331                    }
1332                }
1333                ensureBootCompleted();
1334            } break;
1335            case SHOW_FACTORY_ERROR_MSG: {
1336                Dialog d = new FactoryErrorDialog(
1337                    mContext, msg.getData().getCharSequence("msg"));
1338                d.show();
1339                ensureBootCompleted();
1340            } break;
1341            case UPDATE_CONFIGURATION_MSG: {
1342                final ContentResolver resolver = mContext.getContentResolver();
1343                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1344            } break;
1345            case GC_BACKGROUND_PROCESSES_MSG: {
1346                synchronized (ActivityManagerService.this) {
1347                    performAppGcsIfAppropriateLocked();
1348                }
1349            } break;
1350            case WAIT_FOR_DEBUGGER_MSG: {
1351                synchronized (ActivityManagerService.this) {
1352                    ProcessRecord app = (ProcessRecord)msg.obj;
1353                    if (msg.arg1 != 0) {
1354                        if (!app.waitedForDebugger) {
1355                            Dialog d = new AppWaitingForDebuggerDialog(
1356                                    ActivityManagerService.this,
1357                                    mContext, app);
1358                            app.waitDialog = d;
1359                            app.waitedForDebugger = true;
1360                            d.show();
1361                        }
1362                    } else {
1363                        if (app.waitDialog != null) {
1364                            app.waitDialog.dismiss();
1365                            app.waitDialog = null;
1366                        }
1367                    }
1368                }
1369            } break;
1370            case SERVICE_TIMEOUT_MSG: {
1371                if (mDidDexOpt) {
1372                    mDidDexOpt = false;
1373                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1374                    nmsg.obj = msg.obj;
1375                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1376                    return;
1377                }
1378                mServices.serviceTimeout((ProcessRecord)msg.obj);
1379            } break;
1380            case UPDATE_TIME_ZONE: {
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.updateTimeZone();
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1389                            }
1390                        }
1391                    }
1392                }
1393            } break;
1394            case CLEAR_DNS_CACHE_MSG: {
1395                synchronized (ActivityManagerService.this) {
1396                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1397                        ProcessRecord r = mLruProcesses.get(i);
1398                        if (r.thread != null) {
1399                            try {
1400                                r.thread.clearDnsCache();
1401                            } catch (RemoteException ex) {
1402                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1403                            }
1404                        }
1405                    }
1406                }
1407            } break;
1408            case UPDATE_HTTP_PROXY_MSG: {
1409                ProxyInfo proxy = (ProxyInfo)msg.obj;
1410                String host = "";
1411                String port = "";
1412                String exclList = "";
1413                Uri pacFileUrl = Uri.EMPTY;
1414                if (proxy != null) {
1415                    host = proxy.getHost();
1416                    port = Integer.toString(proxy.getPort());
1417                    exclList = proxy.getExclusionListAsString();
1418                    pacFileUrl = proxy.getPacFileUrl();
1419                }
1420                synchronized (ActivityManagerService.this) {
1421                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1422                        ProcessRecord r = mLruProcesses.get(i);
1423                        if (r.thread != null) {
1424                            try {
1425                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1426                            } catch (RemoteException ex) {
1427                                Slog.w(TAG, "Failed to update http proxy for: " +
1428                                        r.info.processName);
1429                            }
1430                        }
1431                    }
1432                }
1433            } break;
1434            case SHOW_UID_ERROR_MSG: {
1435                String title = "System UIDs Inconsistent";
1436                String text = "UIDs on the system are inconsistent, you need to wipe your"
1437                        + " data partition or your device will be unstable.";
1438                Log.e(TAG, title + ": " + text);
1439                if (mShowDialogs) {
1440                    // XXX This is a temporary dialog, no need to localize.
1441                    AlertDialog d = new BaseErrorDialog(mContext);
1442                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1443                    d.setCancelable(false);
1444                    d.setTitle(title);
1445                    d.setMessage(text);
1446                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1447                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1448                    mUidAlert = d;
1449                    d.show();
1450                }
1451            } break;
1452            case IM_FEELING_LUCKY_MSG: {
1453                if (mUidAlert != null) {
1454                    mUidAlert.dismiss();
1455                    mUidAlert = null;
1456                }
1457            } break;
1458            case PROC_START_TIMEOUT_MSG: {
1459                if (mDidDexOpt) {
1460                    mDidDexOpt = false;
1461                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1462                    nmsg.obj = msg.obj;
1463                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1464                    return;
1465                }
1466                ProcessRecord app = (ProcessRecord)msg.obj;
1467                synchronized (ActivityManagerService.this) {
1468                    processStartTimedOutLocked(app);
1469                }
1470            } break;
1471            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1472                synchronized (ActivityManagerService.this) {
1473                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1474                }
1475            } break;
1476            case KILL_APPLICATION_MSG: {
1477                synchronized (ActivityManagerService.this) {
1478                    int appid = msg.arg1;
1479                    boolean restart = (msg.arg2 == 1);
1480                    Bundle bundle = (Bundle)msg.obj;
1481                    String pkg = bundle.getString("pkg");
1482                    String reason = bundle.getString("reason");
1483                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1484                            false, UserHandle.USER_ALL, reason);
1485                }
1486            } break;
1487            case FINALIZE_PENDING_INTENT_MSG: {
1488                ((PendingIntentRecord)msg.obj).completeFinalize();
1489            } break;
1490            case POST_HEAVY_NOTIFICATION_MSG: {
1491                INotificationManager inm = NotificationManager.getService();
1492                if (inm == null) {
1493                    return;
1494                }
1495
1496                ActivityRecord root = (ActivityRecord)msg.obj;
1497                ProcessRecord process = root.app;
1498                if (process == null) {
1499                    return;
1500                }
1501
1502                try {
1503                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1504                    String text = mContext.getString(R.string.heavy_weight_notification,
1505                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1506                    Notification notification = new Notification();
1507                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1508                    notification.when = 0;
1509                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1510                    notification.tickerText = text;
1511                    notification.defaults = 0; // please be quiet
1512                    notification.sound = null;
1513                    notification.vibrate = null;
1514                    notification.color = mContext.getResources().getColor(
1515                            com.android.internal.R.color.system_notification_accent_color);
1516                    notification.setLatestEventInfo(context, text,
1517                            mContext.getText(R.string.heavy_weight_notification_detail),
1518                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1519                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1520                                    new UserHandle(root.userId)));
1521
1522                    try {
1523                        int[] outId = new int[1];
1524                        inm.enqueueNotificationWithTag("android", "android", null,
1525                                R.string.heavy_weight_notification,
1526                                notification, outId, root.userId);
1527                    } catch (RuntimeException e) {
1528                        Slog.w(ActivityManagerService.TAG,
1529                                "Error showing notification for heavy-weight app", e);
1530                    } catch (RemoteException e) {
1531                    }
1532                } catch (NameNotFoundException e) {
1533                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1534                }
1535            } break;
1536            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1537                INotificationManager inm = NotificationManager.getService();
1538                if (inm == null) {
1539                    return;
1540                }
1541                try {
1542                    inm.cancelNotificationWithTag("android", null,
1543                            R.string.heavy_weight_notification,  msg.arg1);
1544                } catch (RuntimeException e) {
1545                    Slog.w(ActivityManagerService.TAG,
1546                            "Error canceling notification for service", e);
1547                } catch (RemoteException e) {
1548                }
1549            } break;
1550            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1551                synchronized (ActivityManagerService.this) {
1552                    checkExcessivePowerUsageLocked(true);
1553                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1554                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1555                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1556                }
1557            } break;
1558            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1559                synchronized (ActivityManagerService.this) {
1560                    ActivityRecord ar = (ActivityRecord)msg.obj;
1561                    if (mCompatModeDialog != null) {
1562                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1563                                ar.info.applicationInfo.packageName)) {
1564                            return;
1565                        }
1566                        mCompatModeDialog.dismiss();
1567                        mCompatModeDialog = null;
1568                    }
1569                    if (ar != null && false) {
1570                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1571                                ar.packageName)) {
1572                            int mode = mCompatModePackages.computeCompatModeLocked(
1573                                    ar.info.applicationInfo);
1574                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1575                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1576                                mCompatModeDialog = new CompatModeDialog(
1577                                        ActivityManagerService.this, mContext,
1578                                        ar.info.applicationInfo);
1579                                mCompatModeDialog.show();
1580                            }
1581                        }
1582                    }
1583                }
1584                break;
1585            }
1586            case DISPATCH_PROCESSES_CHANGED: {
1587                dispatchProcessesChanged();
1588                break;
1589            }
1590            case DISPATCH_PROCESS_DIED: {
1591                final int pid = msg.arg1;
1592                final int uid = msg.arg2;
1593                dispatchProcessDied(pid, uid);
1594                break;
1595            }
1596            case REPORT_MEM_USAGE_MSG: {
1597                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1598                Thread thread = new Thread() {
1599                    @Override public void run() {
1600                        final SparseArray<ProcessMemInfo> infoMap
1601                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1602                        for (int i=0, N=memInfos.size(); i<N; i++) {
1603                            ProcessMemInfo mi = memInfos.get(i);
1604                            infoMap.put(mi.pid, mi);
1605                        }
1606                        updateCpuStatsNow();
1607                        synchronized (mProcessCpuTracker) {
1608                            final int N = mProcessCpuTracker.countStats();
1609                            for (int i=0; i<N; i++) {
1610                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1611                                if (st.vsize > 0) {
1612                                    long pss = Debug.getPss(st.pid, null);
1613                                    if (pss > 0) {
1614                                        if (infoMap.indexOfKey(st.pid) < 0) {
1615                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1616                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1617                                            mi.pss = pss;
1618                                            memInfos.add(mi);
1619                                        }
1620                                    }
1621                                }
1622                            }
1623                        }
1624
1625                        long totalPss = 0;
1626                        for (int i=0, N=memInfos.size(); i<N; i++) {
1627                            ProcessMemInfo mi = memInfos.get(i);
1628                            if (mi.pss == 0) {
1629                                mi.pss = Debug.getPss(mi.pid, null);
1630                            }
1631                            totalPss += mi.pss;
1632                        }
1633                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1634                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1635                                if (lhs.oomAdj != rhs.oomAdj) {
1636                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1637                                }
1638                                if (lhs.pss != rhs.pss) {
1639                                    return lhs.pss < rhs.pss ? 1 : -1;
1640                                }
1641                                return 0;
1642                            }
1643                        });
1644
1645                        StringBuilder tag = new StringBuilder(128);
1646                        StringBuilder stack = new StringBuilder(128);
1647                        tag.append("Low on memory -- ");
1648                        appendMemBucket(tag, totalPss, "total", false);
1649                        appendMemBucket(stack, totalPss, "total", true);
1650
1651                        StringBuilder logBuilder = new StringBuilder(1024);
1652                        logBuilder.append("Low on memory:\n");
1653
1654                        boolean firstLine = true;
1655                        int lastOomAdj = Integer.MIN_VALUE;
1656                        for (int i=0, N=memInfos.size(); i<N; i++) {
1657                            ProcessMemInfo mi = memInfos.get(i);
1658
1659                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1660                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1661                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1662                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1663                                if (lastOomAdj != mi.oomAdj) {
1664                                    lastOomAdj = mi.oomAdj;
1665                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1666                                        tag.append(" / ");
1667                                    }
1668                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1669                                        if (firstLine) {
1670                                            stack.append(":");
1671                                            firstLine = false;
1672                                        }
1673                                        stack.append("\n\t at ");
1674                                    } else {
1675                                        stack.append("$");
1676                                    }
1677                                } else {
1678                                    tag.append(" ");
1679                                    stack.append("$");
1680                                }
1681                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1682                                    appendMemBucket(tag, mi.pss, mi.name, false);
1683                                }
1684                                appendMemBucket(stack, mi.pss, mi.name, true);
1685                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1686                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1687                                    stack.append("(");
1688                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1689                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1690                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1691                                            stack.append(":");
1692                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1693                                        }
1694                                    }
1695                                    stack.append(")");
1696                                }
1697                            }
1698
1699                            logBuilder.append("  ");
1700                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1701                            logBuilder.append(' ');
1702                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1703                            logBuilder.append(' ');
1704                            ProcessList.appendRamKb(logBuilder, mi.pss);
1705                            logBuilder.append(" kB: ");
1706                            logBuilder.append(mi.name);
1707                            logBuilder.append(" (");
1708                            logBuilder.append(mi.pid);
1709                            logBuilder.append(") ");
1710                            logBuilder.append(mi.adjType);
1711                            logBuilder.append('\n');
1712                            if (mi.adjReason != null) {
1713                                logBuilder.append("                      ");
1714                                logBuilder.append(mi.adjReason);
1715                                logBuilder.append('\n');
1716                            }
1717                        }
1718
1719                        logBuilder.append("           ");
1720                        ProcessList.appendRamKb(logBuilder, totalPss);
1721                        logBuilder.append(" kB: TOTAL\n");
1722
1723                        long[] infos = new long[Debug.MEMINFO_COUNT];
1724                        Debug.getMemInfo(infos);
1725                        logBuilder.append("  MemInfo: ");
1726                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1727                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1728                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1729                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1730                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1731                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1732                            logBuilder.append("  ZRAM: ");
1733                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1734                            logBuilder.append(" kB RAM, ");
1735                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1736                            logBuilder.append(" kB swap total, ");
1737                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1738                            logBuilder.append(" kB swap free\n");
1739                        }
1740                        Slog.i(TAG, logBuilder.toString());
1741
1742                        StringBuilder dropBuilder = new StringBuilder(1024);
1743                        /*
1744                        StringWriter oomSw = new StringWriter();
1745                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1746                        StringWriter catSw = new StringWriter();
1747                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1748                        String[] emptyArgs = new String[] { };
1749                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1750                        oomPw.flush();
1751                        String oomString = oomSw.toString();
1752                        */
1753                        dropBuilder.append(stack);
1754                        dropBuilder.append('\n');
1755                        dropBuilder.append('\n');
1756                        dropBuilder.append(logBuilder);
1757                        dropBuilder.append('\n');
1758                        /*
1759                        dropBuilder.append(oomString);
1760                        dropBuilder.append('\n');
1761                        */
1762                        StringWriter catSw = new StringWriter();
1763                        synchronized (ActivityManagerService.this) {
1764                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1765                            String[] emptyArgs = new String[] { };
1766                            catPw.println();
1767                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1768                            catPw.println();
1769                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1770                                    false, false, null);
1771                            catPw.println();
1772                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1773                            catPw.flush();
1774                        }
1775                        dropBuilder.append(catSw.toString());
1776                        addErrorToDropBox("lowmem", null, "system_server", null,
1777                                null, tag.toString(), dropBuilder.toString(), null, null);
1778                        //Slog.i(TAG, "Sent to dropbox:");
1779                        //Slog.i(TAG, dropBuilder.toString());
1780                        synchronized (ActivityManagerService.this) {
1781                            long now = SystemClock.uptimeMillis();
1782                            if (mLastMemUsageReportTime < now) {
1783                                mLastMemUsageReportTime = now;
1784                            }
1785                        }
1786                    }
1787                };
1788                thread.start();
1789                break;
1790            }
1791            case START_USER_SWITCH_MSG: {
1792                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1793                break;
1794            }
1795            case REPORT_USER_SWITCH_MSG: {
1796                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1797                break;
1798            }
1799            case CONTINUE_USER_SWITCH_MSG: {
1800                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1801                break;
1802            }
1803            case USER_SWITCH_TIMEOUT_MSG: {
1804                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1805                break;
1806            }
1807            case IMMERSIVE_MODE_LOCK_MSG: {
1808                final boolean nextState = (msg.arg1 != 0);
1809                if (mUpdateLock.isHeld() != nextState) {
1810                    if (DEBUG_IMMERSIVE) {
1811                        final ActivityRecord r = (ActivityRecord) msg.obj;
1812                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1813                    }
1814                    if (nextState) {
1815                        mUpdateLock.acquire();
1816                    } else {
1817                        mUpdateLock.release();
1818                    }
1819                }
1820                break;
1821            }
1822            case PERSIST_URI_GRANTS_MSG: {
1823                writeGrantedUriPermissions();
1824                break;
1825            }
1826            case REQUEST_ALL_PSS_MSG: {
1827                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1828                break;
1829            }
1830            case START_PROFILES_MSG: {
1831                synchronized (ActivityManagerService.this) {
1832                    startProfilesLocked();
1833                }
1834                break;
1835            }
1836            case UPDATE_TIME: {
1837                synchronized (ActivityManagerService.this) {
1838                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1839                        ProcessRecord r = mLruProcesses.get(i);
1840                        if (r.thread != null) {
1841                            try {
1842                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1843                            } catch (RemoteException ex) {
1844                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1845                            }
1846                        }
1847                    }
1848                }
1849                break;
1850            }
1851            case SYSTEM_USER_START_MSG: {
1852                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1853                        Integer.toString(msg.arg1), msg.arg1);
1854                mSystemServiceManager.startUser(msg.arg1);
1855                break;
1856            }
1857            case SYSTEM_USER_CURRENT_MSG: {
1858                mBatteryStatsService.noteEvent(
1859                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1860                        Integer.toString(msg.arg2), msg.arg2);
1861                mBatteryStatsService.noteEvent(
1862                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1863                        Integer.toString(msg.arg1), msg.arg1);
1864                mSystemServiceManager.switchUser(msg.arg1);
1865                mLockToAppRequest.clearPrompt();
1866                break;
1867            }
1868            case ENTER_ANIMATION_COMPLETE_MSG: {
1869                synchronized (ActivityManagerService.this) {
1870                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1871                    if (r != null && r.app != null && r.app.thread != null) {
1872                        try {
1873                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1874                        } catch (RemoteException e) {
1875                        }
1876                    }
1877                }
1878                break;
1879            }
1880            case FINISH_BOOTING_MSG: {
1881                if (msg.arg1 != 0) {
1882                    finishBooting();
1883                }
1884                if (msg.arg2 != 0) {
1885                    enableScreenAfterBoot();
1886                }
1887                break;
1888            }
1889            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1890                try {
1891                    Locale l = (Locale) msg.obj;
1892                    IBinder service = ServiceManager.getService("mount");
1893                    IMountService mountService = IMountService.Stub.asInterface(service);
1894                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1895                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1896                } catch (RemoteException e) {
1897                    Log.e(TAG, "Error storing locale for decryption UI", e);
1898                }
1899                break;
1900            }
1901            }
1902        }
1903    };
1904
1905    static final int COLLECT_PSS_BG_MSG = 1;
1906
1907    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1908        @Override
1909        public void handleMessage(Message msg) {
1910            switch (msg.what) {
1911            case COLLECT_PSS_BG_MSG: {
1912                long start = SystemClock.uptimeMillis();
1913                MemInfoReader memInfo = null;
1914                synchronized (ActivityManagerService.this) {
1915                    if (mFullPssPending) {
1916                        mFullPssPending = false;
1917                        memInfo = new MemInfoReader();
1918                    }
1919                }
1920                if (memInfo != null) {
1921                    updateCpuStatsNow();
1922                    long nativeTotalPss = 0;
1923                    synchronized (mProcessCpuTracker) {
1924                        final int N = mProcessCpuTracker.countStats();
1925                        for (int j=0; j<N; j++) {
1926                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1927                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1928                                // This is definitely an application process; skip it.
1929                                continue;
1930                            }
1931                            synchronized (mPidsSelfLocked) {
1932                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1933                                    // This is one of our own processes; skip it.
1934                                    continue;
1935                                }
1936                            }
1937                            nativeTotalPss += Debug.getPss(st.pid, null);
1938                        }
1939                    }
1940                    memInfo.readMemInfo();
1941                    synchronized (ActivityManagerService.this) {
1942                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1943                                + (SystemClock.uptimeMillis()-start) + "ms");
1944                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1945                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1946                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1947                                        +memInfo.getSlabSizeKb(),
1948                                nativeTotalPss);
1949                    }
1950                }
1951
1952                int i=0, num=0;
1953                long[] tmp = new long[1];
1954                do {
1955                    ProcessRecord proc;
1956                    int procState;
1957                    int pid;
1958                    synchronized (ActivityManagerService.this) {
1959                        if (i >= mPendingPssProcesses.size()) {
1960                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1961                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1962                            mPendingPssProcesses.clear();
1963                            return;
1964                        }
1965                        proc = mPendingPssProcesses.get(i);
1966                        procState = proc.pssProcState;
1967                        if (proc.thread != null && procState == proc.setProcState) {
1968                            pid = proc.pid;
1969                        } else {
1970                            proc = null;
1971                            pid = 0;
1972                        }
1973                        i++;
1974                    }
1975                    if (proc != null) {
1976                        long pss = Debug.getPss(pid, tmp);
1977                        synchronized (ActivityManagerService.this) {
1978                            if (proc.thread != null && proc.setProcState == procState
1979                                    && proc.pid == pid) {
1980                                num++;
1981                                proc.lastPssTime = SystemClock.uptimeMillis();
1982                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1983                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1984                                        + ": " + pss + " lastPss=" + proc.lastPss
1985                                        + " state=" + ProcessList.makeProcStateString(procState));
1986                                if (proc.initialIdlePss == 0) {
1987                                    proc.initialIdlePss = pss;
1988                                }
1989                                proc.lastPss = pss;
1990                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1991                                    proc.lastCachedPss = pss;
1992                                }
1993                            }
1994                        }
1995                    }
1996                } while (true);
1997            }
1998            }
1999        }
2000    };
2001
2002    /**
2003     * Monitor for package changes and update our internal state.
2004     */
2005    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2006        @Override
2007        public void onPackageRemoved(String packageName, int uid) {
2008            // Remove all tasks with activities in the specified package from the list of recent tasks
2009            final int eventUserId = getChangingUserId();
2010            synchronized (ActivityManagerService.this) {
2011                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2012                    TaskRecord tr = mRecentTasks.get(i);
2013                    if (tr.userId != eventUserId) continue;
2014
2015                    ComponentName cn = tr.intent.getComponent();
2016                    if (cn != null && cn.getPackageName().equals(packageName)) {
2017                        // If the package name matches, remove the task and kill the process
2018                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2019                    }
2020                }
2021            }
2022        }
2023
2024        @Override
2025        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2026            onPackageModified(packageName);
2027            return true;
2028        }
2029
2030        @Override
2031        public void onPackageModified(String packageName) {
2032            final int eventUserId = getChangingUserId();
2033            final IPackageManager pm = AppGlobals.getPackageManager();
2034            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2035                    new ArrayList<Pair<Intent, Integer>>();
2036            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2037            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2038            // Copy the list of recent tasks so that we don't hold onto the lock on
2039            // ActivityManagerService for long periods while checking if components exist.
2040            synchronized (ActivityManagerService.this) {
2041                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2042                    TaskRecord tr = mRecentTasks.get(i);
2043                    if (tr.userId != eventUserId) continue;
2044
2045                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2046                }
2047            }
2048            // Check the recent tasks and filter out all tasks with components that no longer exist.
2049            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2050                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2051                ComponentName cn = p.first.getComponent();
2052                if (cn != null && cn.getPackageName().equals(packageName)) {
2053                    if (componentsKnownToExist.contains(cn)) {
2054                        // If we know that the component still exists in the package, then skip
2055                        continue;
2056                    }
2057                    try {
2058                        ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2059                        if (info != null) {
2060                            componentsKnownToExist.add(cn);
2061                        } else {
2062                            tasksToRemove.add(p.second);
2063                        }
2064                    } catch (RemoteException e) {
2065                        Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2066                    }
2067                }
2068            }
2069            // Prune all the tasks with removed components from the list of recent tasks
2070            synchronized (ActivityManagerService.this) {
2071                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2072                    // Remove the task but don't kill the process (since other components in that
2073                    // package may still be running and in the background)
2074                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2075                }
2076            }
2077        }
2078
2079        @Override
2080        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2081            // Force stop the specified packages
2082            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2083            if (packages != null) {
2084                for (String pkg : packages) {
2085                    synchronized (ActivityManagerService.this) {
2086                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2087                                userId, "finished booting")) {
2088                            return true;
2089                        }
2090                    }
2091                }
2092            }
2093            return false;
2094        }
2095    };
2096
2097    public void setSystemProcess() {
2098        try {
2099            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2100            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2101            ServiceManager.addService("meminfo", new MemBinder(this));
2102            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2103            ServiceManager.addService("dbinfo", new DbBinder(this));
2104            if (MONITOR_CPU_USAGE) {
2105                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2106            }
2107            ServiceManager.addService("permission", new PermissionController(this));
2108
2109            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2110                    "android", STOCK_PM_FLAGS);
2111            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2112
2113            synchronized (this) {
2114                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2115                app.persistent = true;
2116                app.pid = MY_PID;
2117                app.maxAdj = ProcessList.SYSTEM_ADJ;
2118                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2119                mProcessNames.put(app.processName, app.uid, app);
2120                synchronized (mPidsSelfLocked) {
2121                    mPidsSelfLocked.put(app.pid, app);
2122                }
2123                updateLruProcessLocked(app, false, null);
2124                updateOomAdjLocked();
2125            }
2126        } catch (PackageManager.NameNotFoundException e) {
2127            throw new RuntimeException(
2128                    "Unable to find android system package", e);
2129        }
2130    }
2131
2132    public void setWindowManager(WindowManagerService wm) {
2133        mWindowManager = wm;
2134        mStackSupervisor.setWindowManager(wm);
2135    }
2136
2137    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2138        mUsageStatsService = usageStatsManager;
2139    }
2140
2141    public void startObservingNativeCrashes() {
2142        final NativeCrashListener ncl = new NativeCrashListener(this);
2143        ncl.start();
2144    }
2145
2146    public IAppOpsService getAppOpsService() {
2147        return mAppOpsService;
2148    }
2149
2150    static class MemBinder extends Binder {
2151        ActivityManagerService mActivityManagerService;
2152        MemBinder(ActivityManagerService activityManagerService) {
2153            mActivityManagerService = activityManagerService;
2154        }
2155
2156        @Override
2157        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2158            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2159                    != PackageManager.PERMISSION_GRANTED) {
2160                pw.println("Permission Denial: can't dump meminfo from from pid="
2161                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2162                        + " without permission " + android.Manifest.permission.DUMP);
2163                return;
2164            }
2165
2166            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2167        }
2168    }
2169
2170    static class GraphicsBinder extends Binder {
2171        ActivityManagerService mActivityManagerService;
2172        GraphicsBinder(ActivityManagerService activityManagerService) {
2173            mActivityManagerService = activityManagerService;
2174        }
2175
2176        @Override
2177        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2178            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2179                    != PackageManager.PERMISSION_GRANTED) {
2180                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2181                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2182                        + " without permission " + android.Manifest.permission.DUMP);
2183                return;
2184            }
2185
2186            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2187        }
2188    }
2189
2190    static class DbBinder extends Binder {
2191        ActivityManagerService mActivityManagerService;
2192        DbBinder(ActivityManagerService activityManagerService) {
2193            mActivityManagerService = activityManagerService;
2194        }
2195
2196        @Override
2197        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2198            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2199                    != PackageManager.PERMISSION_GRANTED) {
2200                pw.println("Permission Denial: can't dump dbinfo from from pid="
2201                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2202                        + " without permission " + android.Manifest.permission.DUMP);
2203                return;
2204            }
2205
2206            mActivityManagerService.dumpDbInfo(fd, pw, args);
2207        }
2208    }
2209
2210    static class CpuBinder extends Binder {
2211        ActivityManagerService mActivityManagerService;
2212        CpuBinder(ActivityManagerService activityManagerService) {
2213            mActivityManagerService = activityManagerService;
2214        }
2215
2216        @Override
2217        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2218            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2219                    != PackageManager.PERMISSION_GRANTED) {
2220                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2221                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2222                        + " without permission " + android.Manifest.permission.DUMP);
2223                return;
2224            }
2225
2226            synchronized (mActivityManagerService.mProcessCpuTracker) {
2227                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2228                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2229                        SystemClock.uptimeMillis()));
2230            }
2231        }
2232    }
2233
2234    public static final class Lifecycle extends SystemService {
2235        private final ActivityManagerService mService;
2236
2237        public Lifecycle(Context context) {
2238            super(context);
2239            mService = new ActivityManagerService(context);
2240        }
2241
2242        @Override
2243        public void onStart() {
2244            mService.start();
2245        }
2246
2247        public ActivityManagerService getService() {
2248            return mService;
2249        }
2250    }
2251
2252    // Note: This method is invoked on the main thread but may need to attach various
2253    // handlers to other threads.  So take care to be explicit about the looper.
2254    public ActivityManagerService(Context systemContext) {
2255        mContext = systemContext;
2256        mFactoryTest = FactoryTest.getMode();
2257        mSystemThread = ActivityThread.currentActivityThread();
2258
2259        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2260
2261        mHandlerThread = new ServiceThread(TAG,
2262                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2263        mHandlerThread.start();
2264        mHandler = new MainHandler(mHandlerThread.getLooper());
2265
2266        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2267                "foreground", BROADCAST_FG_TIMEOUT, false);
2268        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2269                "background", BROADCAST_BG_TIMEOUT, true);
2270        mBroadcastQueues[0] = mFgBroadcastQueue;
2271        mBroadcastQueues[1] = mBgBroadcastQueue;
2272
2273        mServices = new ActiveServices(this);
2274        mProviderMap = new ProviderMap(this);
2275
2276        // TODO: Move creation of battery stats service outside of activity manager service.
2277        File dataDir = Environment.getDataDirectory();
2278        File systemDir = new File(dataDir, "system");
2279        systemDir.mkdirs();
2280        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2281        mBatteryStatsService.getActiveStatistics().readLocked();
2282        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2283        mOnBattery = DEBUG_POWER ? true
2284                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2285        mBatteryStatsService.getActiveStatistics().setCallback(this);
2286
2287        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2288
2289        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2290
2291        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2292
2293        // User 0 is the first and only user that runs at boot.
2294        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2295        mUserLru.add(Integer.valueOf(0));
2296        updateStartedUserArrayLocked();
2297
2298        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2299            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2300
2301        mConfiguration.setToDefaults();
2302        mConfiguration.setLocale(Locale.getDefault());
2303
2304        mConfigurationSeq = mConfiguration.seq = 1;
2305        mProcessCpuTracker.init();
2306
2307        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2308        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2309        mStackSupervisor = new ActivityStackSupervisor(this);
2310        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2311
2312        mProcessCpuThread = new Thread("CpuTracker") {
2313            @Override
2314            public void run() {
2315                while (true) {
2316                    try {
2317                        try {
2318                            synchronized(this) {
2319                                final long now = SystemClock.uptimeMillis();
2320                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2321                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2322                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2323                                //        + ", write delay=" + nextWriteDelay);
2324                                if (nextWriteDelay < nextCpuDelay) {
2325                                    nextCpuDelay = nextWriteDelay;
2326                                }
2327                                if (nextCpuDelay > 0) {
2328                                    mProcessCpuMutexFree.set(true);
2329                                    this.wait(nextCpuDelay);
2330                                }
2331                            }
2332                        } catch (InterruptedException e) {
2333                        }
2334                        updateCpuStatsNow();
2335                    } catch (Exception e) {
2336                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2337                    }
2338                }
2339            }
2340        };
2341
2342        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2343
2344        Watchdog.getInstance().addMonitor(this);
2345        Watchdog.getInstance().addThread(mHandler);
2346    }
2347
2348    public void setSystemServiceManager(SystemServiceManager mgr) {
2349        mSystemServiceManager = mgr;
2350    }
2351
2352    private void start() {
2353        Process.removeAllProcessGroups();
2354        mProcessCpuThread.start();
2355
2356        mBatteryStatsService.publish(mContext);
2357        mAppOpsService.publish(mContext);
2358        Slog.d("AppOps", "AppOpsService published");
2359        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2360    }
2361
2362    public void initPowerManagement() {
2363        mStackSupervisor.initPowerManagement();
2364        mBatteryStatsService.initPowerManagement();
2365    }
2366
2367    @Override
2368    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2369            throws RemoteException {
2370        if (code == SYSPROPS_TRANSACTION) {
2371            // We need to tell all apps about the system property change.
2372            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2373            synchronized(this) {
2374                final int NP = mProcessNames.getMap().size();
2375                for (int ip=0; ip<NP; ip++) {
2376                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2377                    final int NA = apps.size();
2378                    for (int ia=0; ia<NA; ia++) {
2379                        ProcessRecord app = apps.valueAt(ia);
2380                        if (app.thread != null) {
2381                            procs.add(app.thread.asBinder());
2382                        }
2383                    }
2384                }
2385            }
2386
2387            int N = procs.size();
2388            for (int i=0; i<N; i++) {
2389                Parcel data2 = Parcel.obtain();
2390                try {
2391                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2392                } catch (RemoteException e) {
2393                }
2394                data2.recycle();
2395            }
2396        }
2397        try {
2398            return super.onTransact(code, data, reply, flags);
2399        } catch (RuntimeException e) {
2400            // The activity manager only throws security exceptions, so let's
2401            // log all others.
2402            if (!(e instanceof SecurityException)) {
2403                Slog.wtf(TAG, "Activity Manager Crash", e);
2404            }
2405            throw e;
2406        }
2407    }
2408
2409    void updateCpuStats() {
2410        final long now = SystemClock.uptimeMillis();
2411        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2412            return;
2413        }
2414        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2415            synchronized (mProcessCpuThread) {
2416                mProcessCpuThread.notify();
2417            }
2418        }
2419    }
2420
2421    void updateCpuStatsNow() {
2422        synchronized (mProcessCpuTracker) {
2423            mProcessCpuMutexFree.set(false);
2424            final long now = SystemClock.uptimeMillis();
2425            boolean haveNewCpuStats = false;
2426
2427            if (MONITOR_CPU_USAGE &&
2428                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2429                mLastCpuTime.set(now);
2430                haveNewCpuStats = true;
2431                mProcessCpuTracker.update();
2432                //Slog.i(TAG, mProcessCpu.printCurrentState());
2433                //Slog.i(TAG, "Total CPU usage: "
2434                //        + mProcessCpu.getTotalCpuPercent() + "%");
2435
2436                // Slog the cpu usage if the property is set.
2437                if ("true".equals(SystemProperties.get("events.cpu"))) {
2438                    int user = mProcessCpuTracker.getLastUserTime();
2439                    int system = mProcessCpuTracker.getLastSystemTime();
2440                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2441                    int irq = mProcessCpuTracker.getLastIrqTime();
2442                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2443                    int idle = mProcessCpuTracker.getLastIdleTime();
2444
2445                    int total = user + system + iowait + irq + softIrq + idle;
2446                    if (total == 0) total = 1;
2447
2448                    EventLog.writeEvent(EventLogTags.CPU,
2449                            ((user+system+iowait+irq+softIrq) * 100) / total,
2450                            (user * 100) / total,
2451                            (system * 100) / total,
2452                            (iowait * 100) / total,
2453                            (irq * 100) / total,
2454                            (softIrq * 100) / total);
2455                }
2456            }
2457
2458            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2459            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2460            synchronized(bstats) {
2461                synchronized(mPidsSelfLocked) {
2462                    if (haveNewCpuStats) {
2463                        if (mOnBattery) {
2464                            int perc = bstats.startAddingCpuLocked();
2465                            int totalUTime = 0;
2466                            int totalSTime = 0;
2467                            final int N = mProcessCpuTracker.countStats();
2468                            for (int i=0; i<N; i++) {
2469                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2470                                if (!st.working) {
2471                                    continue;
2472                                }
2473                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2474                                int otherUTime = (st.rel_utime*perc)/100;
2475                                int otherSTime = (st.rel_stime*perc)/100;
2476                                totalUTime += otherUTime;
2477                                totalSTime += otherSTime;
2478                                if (pr != null) {
2479                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2480                                    if (ps == null || !ps.isActive()) {
2481                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2482                                                pr.info.uid, pr.processName);
2483                                    }
2484                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2485                                            st.rel_stime-otherSTime);
2486                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2487                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2488                                } else {
2489                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2490                                    if (ps == null || !ps.isActive()) {
2491                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2492                                                bstats.mapUid(st.uid), st.name);
2493                                    }
2494                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2495                                            st.rel_stime-otherSTime);
2496                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2497                                }
2498                            }
2499                            bstats.finishAddingCpuLocked(perc, totalUTime,
2500                                    totalSTime, cpuSpeedTimes);
2501                        }
2502                    }
2503                }
2504
2505                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2506                    mLastWriteTime = now;
2507                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2508                }
2509            }
2510        }
2511    }
2512
2513    @Override
2514    public void batteryNeedsCpuUpdate() {
2515        updateCpuStatsNow();
2516    }
2517
2518    @Override
2519    public void batteryPowerChanged(boolean onBattery) {
2520        // When plugging in, update the CPU stats first before changing
2521        // the plug state.
2522        updateCpuStatsNow();
2523        synchronized (this) {
2524            synchronized(mPidsSelfLocked) {
2525                mOnBattery = DEBUG_POWER ? true : onBattery;
2526            }
2527        }
2528    }
2529
2530    /**
2531     * Initialize the application bind args. These are passed to each
2532     * process when the bindApplication() IPC is sent to the process. They're
2533     * lazily setup to make sure the services are running when they're asked for.
2534     */
2535    private HashMap<String, IBinder> getCommonServicesLocked() {
2536        if (mAppBindArgs == null) {
2537            mAppBindArgs = new HashMap<String, IBinder>();
2538
2539            // Setup the application init args
2540            mAppBindArgs.put("package", ServiceManager.getService("package"));
2541            mAppBindArgs.put("window", ServiceManager.getService("window"));
2542            mAppBindArgs.put(Context.ALARM_SERVICE,
2543                    ServiceManager.getService(Context.ALARM_SERVICE));
2544        }
2545        return mAppBindArgs;
2546    }
2547
2548    final void setFocusedActivityLocked(ActivityRecord r) {
2549        if (mFocusedActivity != r) {
2550            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2551            mFocusedActivity = r;
2552            if (r.task != null && r.task.voiceInteractor != null) {
2553                startRunningVoiceLocked();
2554            } else {
2555                finishRunningVoiceLocked();
2556            }
2557            mStackSupervisor.setFocusedStack(r);
2558            if (r != null) {
2559                mWindowManager.setFocusedApp(r.appToken, true);
2560            }
2561            applyUpdateLockStateLocked(r);
2562        }
2563    }
2564
2565    final void clearFocusedActivity(ActivityRecord r) {
2566        if (mFocusedActivity == r) {
2567            mFocusedActivity = null;
2568        }
2569    }
2570
2571    @Override
2572    public void setFocusedStack(int stackId) {
2573        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2574        synchronized (ActivityManagerService.this) {
2575            ActivityStack stack = mStackSupervisor.getStack(stackId);
2576            if (stack != null) {
2577                ActivityRecord r = stack.topRunningActivityLocked(null);
2578                if (r != null) {
2579                    setFocusedActivityLocked(r);
2580                }
2581            }
2582        }
2583    }
2584
2585    @Override
2586    public void notifyActivityDrawn(IBinder token) {
2587        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2588        synchronized (this) {
2589            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2590            if (r != null) {
2591                r.task.stack.notifyActivityDrawnLocked(r);
2592            }
2593        }
2594    }
2595
2596    final void applyUpdateLockStateLocked(ActivityRecord r) {
2597        // Modifications to the UpdateLock state are done on our handler, outside
2598        // the activity manager's locks.  The new state is determined based on the
2599        // state *now* of the relevant activity record.  The object is passed to
2600        // the handler solely for logging detail, not to be consulted/modified.
2601        final boolean nextState = r != null && r.immersive;
2602        mHandler.sendMessage(
2603                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2604    }
2605
2606    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2607        Message msg = Message.obtain();
2608        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2609        msg.obj = r.task.askedCompatMode ? null : r;
2610        mHandler.sendMessage(msg);
2611    }
2612
2613    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2614            String what, Object obj, ProcessRecord srcApp) {
2615        app.lastActivityTime = now;
2616
2617        if (app.activities.size() > 0) {
2618            // Don't want to touch dependent processes that are hosting activities.
2619            return index;
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623        if (lrui < 0) {
2624            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2625                    + what + " " + obj + " from " + srcApp);
2626            return index;
2627        }
2628
2629        if (lrui >= index) {
2630            // Don't want to cause this to move dependent processes *back* in the
2631            // list as if they were less frequently used.
2632            return index;
2633        }
2634
2635        if (lrui >= mLruProcessActivityStart) {
2636            // Don't want to touch dependent processes that are hosting activities.
2637            return index;
2638        }
2639
2640        mLruProcesses.remove(lrui);
2641        if (index > 0) {
2642            index--;
2643        }
2644        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2645                + " in LRU list: " + app);
2646        mLruProcesses.add(index, app);
2647        return index;
2648    }
2649
2650    final void removeLruProcessLocked(ProcessRecord app) {
2651        int lrui = mLruProcesses.lastIndexOf(app);
2652        if (lrui >= 0) {
2653            if (!app.killed) {
2654                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2655                Process.killProcessQuiet(app.pid);
2656                Process.killProcessGroup(app.info.uid, app.pid);
2657            }
2658            if (lrui <= mLruProcessActivityStart) {
2659                mLruProcessActivityStart--;
2660            }
2661            if (lrui <= mLruProcessServiceStart) {
2662                mLruProcessServiceStart--;
2663            }
2664            mLruProcesses.remove(lrui);
2665        }
2666    }
2667
2668    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2669            ProcessRecord client) {
2670        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2671                || app.treatLikeActivity;
2672        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2673        if (!activityChange && hasActivity) {
2674            // The process has activities, so we are only allowing activity-based adjustments
2675            // to move it.  It should be kept in the front of the list with other
2676            // processes that have activities, and we don't want those to change their
2677            // order except due to activity operations.
2678            return;
2679        }
2680
2681        mLruSeq++;
2682        final long now = SystemClock.uptimeMillis();
2683        app.lastActivityTime = now;
2684
2685        // First a quick reject: if the app is already at the position we will
2686        // put it, then there is nothing to do.
2687        if (hasActivity) {
2688            final int N = mLruProcesses.size();
2689            if (N > 0 && mLruProcesses.get(N-1) == app) {
2690                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2691                return;
2692            }
2693        } else {
2694            if (mLruProcessServiceStart > 0
2695                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2696                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2697                return;
2698            }
2699        }
2700
2701        int lrui = mLruProcesses.lastIndexOf(app);
2702
2703        if (app.persistent && lrui >= 0) {
2704            // We don't care about the position of persistent processes, as long as
2705            // they are in the list.
2706            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2707            return;
2708        }
2709
2710        /* In progress: compute new position first, so we can avoid doing work
2711           if the process is not actually going to move.  Not yet working.
2712        int addIndex;
2713        int nextIndex;
2714        boolean inActivity = false, inService = false;
2715        if (hasActivity) {
2716            // Process has activities, put it at the very tipsy-top.
2717            addIndex = mLruProcesses.size();
2718            nextIndex = mLruProcessServiceStart;
2719            inActivity = true;
2720        } else if (hasService) {
2721            // Process has services, put it at the top of the service list.
2722            addIndex = mLruProcessActivityStart;
2723            nextIndex = mLruProcessServiceStart;
2724            inActivity = true;
2725            inService = true;
2726        } else  {
2727            // Process not otherwise of interest, it goes to the top of the non-service area.
2728            addIndex = mLruProcessServiceStart;
2729            if (client != null) {
2730                int clientIndex = mLruProcesses.lastIndexOf(client);
2731                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2732                        + app);
2733                if (clientIndex >= 0 && addIndex > clientIndex) {
2734                    addIndex = clientIndex;
2735                }
2736            }
2737            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2738        }
2739
2740        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2741                + mLruProcessActivityStart + "): " + app);
2742        */
2743
2744        if (lrui >= 0) {
2745            if (lrui < mLruProcessActivityStart) {
2746                mLruProcessActivityStart--;
2747            }
2748            if (lrui < mLruProcessServiceStart) {
2749                mLruProcessServiceStart--;
2750            }
2751            /*
2752            if (addIndex > lrui) {
2753                addIndex--;
2754            }
2755            if (nextIndex > lrui) {
2756                nextIndex--;
2757            }
2758            */
2759            mLruProcesses.remove(lrui);
2760        }
2761
2762        /*
2763        mLruProcesses.add(addIndex, app);
2764        if (inActivity) {
2765            mLruProcessActivityStart++;
2766        }
2767        if (inService) {
2768            mLruProcessActivityStart++;
2769        }
2770        */
2771
2772        int nextIndex;
2773        if (hasActivity) {
2774            final int N = mLruProcesses.size();
2775            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2776                // Process doesn't have activities, but has clients with
2777                // activities...  move it up, but one below the top (the top
2778                // should always have a real activity).
2779                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2780                mLruProcesses.add(N-1, app);
2781                // To keep it from spamming the LRU list (by making a bunch of clients),
2782                // we will push down any other entries owned by the app.
2783                final int uid = app.info.uid;
2784                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2785                    ProcessRecord subProc = mLruProcesses.get(i);
2786                    if (subProc.info.uid == uid) {
2787                        // We want to push this one down the list.  If the process after
2788                        // it is for the same uid, however, don't do so, because we don't
2789                        // want them internally to be re-ordered.
2790                        if (mLruProcesses.get(i-1).info.uid != uid) {
2791                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2792                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2793                            ProcessRecord tmp = mLruProcesses.get(i);
2794                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2795                            mLruProcesses.set(i-1, tmp);
2796                            i--;
2797                        }
2798                    } else {
2799                        // A gap, we can stop here.
2800                        break;
2801                    }
2802                }
2803            } else {
2804                // Process has activities, put it at the very tipsy-top.
2805                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2806                mLruProcesses.add(app);
2807            }
2808            nextIndex = mLruProcessServiceStart;
2809        } else if (hasService) {
2810            // Process has services, put it at the top of the service list.
2811            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2812            mLruProcesses.add(mLruProcessActivityStart, app);
2813            nextIndex = mLruProcessServiceStart;
2814            mLruProcessActivityStart++;
2815        } else  {
2816            // Process not otherwise of interest, it goes to the top of the non-service area.
2817            int index = mLruProcessServiceStart;
2818            if (client != null) {
2819                // If there is a client, don't allow the process to be moved up higher
2820                // in the list than that client.
2821                int clientIndex = mLruProcesses.lastIndexOf(client);
2822                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2823                        + " when updating " + app);
2824                if (clientIndex <= lrui) {
2825                    // Don't allow the client index restriction to push it down farther in the
2826                    // list than it already is.
2827                    clientIndex = lrui;
2828                }
2829                if (clientIndex >= 0 && index > clientIndex) {
2830                    index = clientIndex;
2831                }
2832            }
2833            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2834            mLruProcesses.add(index, app);
2835            nextIndex = index-1;
2836            mLruProcessActivityStart++;
2837            mLruProcessServiceStart++;
2838        }
2839
2840        // If the app is currently using a content provider or service,
2841        // bump those processes as well.
2842        for (int j=app.connections.size()-1; j>=0; j--) {
2843            ConnectionRecord cr = app.connections.valueAt(j);
2844            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2845                    && cr.binding.service.app != null
2846                    && cr.binding.service.app.lruSeq != mLruSeq
2847                    && !cr.binding.service.app.persistent) {
2848                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2849                        "service connection", cr, app);
2850            }
2851        }
2852        for (int j=app.conProviders.size()-1; j>=0; j--) {
2853            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2854            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2855                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2856                        "provider reference", cpr, app);
2857            }
2858        }
2859    }
2860
2861    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2862        if (uid == Process.SYSTEM_UID) {
2863            // The system gets to run in any process.  If there are multiple
2864            // processes with the same uid, just pick the first (this
2865            // should never happen).
2866            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2867            if (procs == null) return null;
2868            final int N = procs.size();
2869            for (int i = 0; i < N; i++) {
2870                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2871            }
2872        }
2873        ProcessRecord proc = mProcessNames.get(processName, uid);
2874        if (false && proc != null && !keepIfLarge
2875                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2876                && proc.lastCachedPss >= 4000) {
2877            // Turn this condition on to cause killing to happen regularly, for testing.
2878            if (proc.baseProcessTracker != null) {
2879                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2880            }
2881            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2882        } else if (proc != null && !keepIfLarge
2883                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2884                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2885            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2886            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
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            }
2892        }
2893        return proc;
2894    }
2895
2896    void ensurePackageDexOpt(String packageName) {
2897        IPackageManager pm = AppGlobals.getPackageManager();
2898        try {
2899            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2900                mDidDexOpt = true;
2901            }
2902        } catch (RemoteException e) {
2903        }
2904    }
2905
2906    boolean isNextTransitionForward() {
2907        int transit = mWindowManager.getPendingAppTransition();
2908        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2909                || transit == AppTransition.TRANSIT_TASK_OPEN
2910                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2911    }
2912
2913    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2914            String processName, String abiOverride, int uid, Runnable crashHandler) {
2915        synchronized(this) {
2916            ApplicationInfo info = new ApplicationInfo();
2917            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2918            // For isolated processes, the former contains the parent's uid and the latter the
2919            // actual uid of the isolated process.
2920            // In the special case introduced by this method (which is, starting an isolated
2921            // process directly from the SystemServer without an actual parent app process) the
2922            // closest thing to a parent's uid is SYSTEM_UID.
2923            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2924            // the |isolated| logic in the ProcessRecord constructor.
2925            info.uid = Process.SYSTEM_UID;
2926            info.processName = processName;
2927            info.className = entryPoint;
2928            info.packageName = "android";
2929            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2930                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2931                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2932                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2933                    crashHandler);
2934            return proc != null ? proc.pid : 0;
2935        }
2936    }
2937
2938    final ProcessRecord startProcessLocked(String processName,
2939            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2940            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2941            boolean isolated, boolean keepIfLarge) {
2942        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2943                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2944                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2945                null /* crashHandler */);
2946    }
2947
2948    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2949            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2950            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2951            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2952        long startTime = SystemClock.elapsedRealtime();
2953        ProcessRecord app;
2954        if (!isolated) {
2955            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2956            checkTime(startTime, "startProcess: after getProcessRecord");
2957        } else {
2958            // If this is an isolated process, it can't re-use an existing process.
2959            app = null;
2960        }
2961        // We don't have to do anything more if:
2962        // (1) There is an existing application record; and
2963        // (2) The caller doesn't think it is dead, OR there is no thread
2964        //     object attached to it so we know it couldn't have crashed; and
2965        // (3) There is a pid assigned to it, so it is either starting or
2966        //     already running.
2967        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2968                + " app=" + app + " knownToBeDead=" + knownToBeDead
2969                + " thread=" + (app != null ? app.thread : null)
2970                + " pid=" + (app != null ? app.pid : -1));
2971        if (app != null && app.pid > 0) {
2972            if (!knownToBeDead || app.thread == null) {
2973                // We already have the app running, or are waiting for it to
2974                // come up (we have a pid but not yet its thread), so keep it.
2975                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2976                // If this is a new package in the process, add the package to the list
2977                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2978                checkTime(startTime, "startProcess: done, added package to proc");
2979                return app;
2980            }
2981
2982            // An application record is attached to a previous process,
2983            // clean it up now.
2984            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2985            checkTime(startTime, "startProcess: bad proc running, killing");
2986            Process.killProcessGroup(app.info.uid, app.pid);
2987            handleAppDiedLocked(app, true, true);
2988            checkTime(startTime, "startProcess: done killing old proc");
2989        }
2990
2991        String hostingNameStr = hostingName != null
2992                ? hostingName.flattenToShortString() : null;
2993
2994        if (!isolated) {
2995            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2996                // If we are in the background, then check to see if this process
2997                // is bad.  If so, we will just silently fail.
2998                if (mBadProcesses.get(info.processName, info.uid) != null) {
2999                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3000                            + "/" + info.processName);
3001                    return null;
3002                }
3003            } else {
3004                // When the user is explicitly starting a process, then clear its
3005                // crash count so that we won't make it bad until they see at
3006                // least one crash dialog again, and make the process good again
3007                // if it had been bad.
3008                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3009                        + "/" + info.processName);
3010                mProcessCrashTimes.remove(info.processName, info.uid);
3011                if (mBadProcesses.get(info.processName, info.uid) != null) {
3012                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3013                            UserHandle.getUserId(info.uid), info.uid,
3014                            info.processName);
3015                    mBadProcesses.remove(info.processName, info.uid);
3016                    if (app != null) {
3017                        app.bad = false;
3018                    }
3019                }
3020            }
3021        }
3022
3023        if (app == null) {
3024            checkTime(startTime, "startProcess: creating new process record");
3025            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3026            app.crashHandler = crashHandler;
3027            if (app == null) {
3028                Slog.w(TAG, "Failed making new process record for "
3029                        + processName + "/" + info.uid + " isolated=" + isolated);
3030                return null;
3031            }
3032            mProcessNames.put(processName, app.uid, app);
3033            if (isolated) {
3034                mIsolatedProcesses.put(app.uid, app);
3035            }
3036            checkTime(startTime, "startProcess: done creating new process record");
3037        } else {
3038            // If this is a new package in the process, add the package to the list
3039            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3040            checkTime(startTime, "startProcess: added package to existing proc");
3041        }
3042
3043        // If the system is not ready yet, then hold off on starting this
3044        // process until it is.
3045        if (!mProcessesReady
3046                && !isAllowedWhileBooting(info)
3047                && !allowWhileBooting) {
3048            if (!mProcessesOnHold.contains(app)) {
3049                mProcessesOnHold.add(app);
3050            }
3051            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3052            checkTime(startTime, "startProcess: returning with proc on hold");
3053            return app;
3054        }
3055
3056        checkTime(startTime, "startProcess: stepping in to startProcess");
3057        startProcessLocked(
3058                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3059        checkTime(startTime, "startProcess: done starting proc!");
3060        return (app.pid != 0) ? app : null;
3061    }
3062
3063    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3064        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3065    }
3066
3067    private final void startProcessLocked(ProcessRecord app,
3068            String hostingType, String hostingNameStr) {
3069        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3070                null /* entryPoint */, null /* entryPointArgs */);
3071    }
3072
3073    private final void startProcessLocked(ProcessRecord app, String hostingType,
3074            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3075        long startTime = SystemClock.elapsedRealtime();
3076        if (app.pid > 0 && app.pid != MY_PID) {
3077            checkTime(startTime, "startProcess: removing from pids map");
3078            synchronized (mPidsSelfLocked) {
3079                mPidsSelfLocked.remove(app.pid);
3080                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3081            }
3082            checkTime(startTime, "startProcess: done removing from pids map");
3083            app.setPid(0);
3084        }
3085
3086        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3087                "startProcessLocked removing on hold: " + app);
3088        mProcessesOnHold.remove(app);
3089
3090        checkTime(startTime, "startProcess: starting to update cpu stats");
3091        updateCpuStats();
3092        checkTime(startTime, "startProcess: done updating cpu stats");
3093
3094        try {
3095            int uid = app.uid;
3096
3097            int[] gids = null;
3098            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3099            if (!app.isolated) {
3100                int[] permGids = null;
3101                try {
3102                    checkTime(startTime, "startProcess: getting gids from package manager");
3103                    final PackageManager pm = mContext.getPackageManager();
3104                    permGids = pm.getPackageGids(app.info.packageName);
3105
3106                    if (Environment.isExternalStorageEmulated()) {
3107                        checkTime(startTime, "startProcess: checking external storage perm");
3108                        if (pm.checkPermission(
3109                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3110                                app.info.packageName) == PERMISSION_GRANTED) {
3111                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3112                        } else {
3113                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3114                        }
3115                    }
3116                } catch (PackageManager.NameNotFoundException e) {
3117                    Slog.w(TAG, "Unable to retrieve gids", e);
3118                }
3119
3120                /*
3121                 * Add shared application and profile GIDs so applications can share some
3122                 * resources like shared libraries and access user-wide resources
3123                 */
3124                if (permGids == null) {
3125                    gids = new int[2];
3126                } else {
3127                    gids = new int[permGids.length + 2];
3128                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3129                }
3130                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3131                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3132            }
3133            checkTime(startTime, "startProcess: building args");
3134            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3135                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3136                        && mTopComponent != null
3137                        && app.processName.equals(mTopComponent.getPackageName())) {
3138                    uid = 0;
3139                }
3140                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3141                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3142                    uid = 0;
3143                }
3144            }
3145            int debugFlags = 0;
3146            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3147                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3148                // Also turn on CheckJNI for debuggable apps. It's quite
3149                // awkward to turn on otherwise.
3150                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3151            }
3152            // Run the app in safe mode if its manifest requests so or the
3153            // system is booted in safe mode.
3154            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3155                mSafeMode == true) {
3156                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3157            }
3158            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3159                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3160            }
3161            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3162                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3163            }
3164            if ("1".equals(SystemProperties.get("debug.assert"))) {
3165                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3166            }
3167
3168            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3169            if (requiredAbi == null) {
3170                requiredAbi = Build.SUPPORTED_ABIS[0];
3171            }
3172
3173            String instructionSet = null;
3174            if (app.info.primaryCpuAbi != null) {
3175                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3176            }
3177
3178            // Start the process.  It will either succeed and return a result containing
3179            // the PID of the new process, or else throw a RuntimeException.
3180            boolean isActivityProcess = (entryPoint == null);
3181            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3182            checkTime(startTime, "startProcess: asking zygote to start proc");
3183            Process.ProcessStartResult startResult = Process.start(entryPoint,
3184                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3185                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3186                    app.info.dataDir, entryPointArgs);
3187            checkTime(startTime, "startProcess: returned from zygote!");
3188
3189            if (app.isolated) {
3190                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3191            }
3192            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3193            checkTime(startTime, "startProcess: done updating battery stats");
3194
3195            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3196                    UserHandle.getUserId(uid), startResult.pid, uid,
3197                    app.processName, hostingType,
3198                    hostingNameStr != null ? hostingNameStr : "");
3199
3200            if (app.persistent) {
3201                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3202            }
3203
3204            checkTime(startTime, "startProcess: building log message");
3205            StringBuilder buf = mStringBuilder;
3206            buf.setLength(0);
3207            buf.append("Start proc ");
3208            buf.append(app.processName);
3209            if (!isActivityProcess) {
3210                buf.append(" [");
3211                buf.append(entryPoint);
3212                buf.append("]");
3213            }
3214            buf.append(" for ");
3215            buf.append(hostingType);
3216            if (hostingNameStr != null) {
3217                buf.append(" ");
3218                buf.append(hostingNameStr);
3219            }
3220            buf.append(": pid=");
3221            buf.append(startResult.pid);
3222            buf.append(" uid=");
3223            buf.append(uid);
3224            buf.append(" gids={");
3225            if (gids != null) {
3226                for (int gi=0; gi<gids.length; gi++) {
3227                    if (gi != 0) buf.append(", ");
3228                    buf.append(gids[gi]);
3229
3230                }
3231            }
3232            buf.append("}");
3233            if (requiredAbi != null) {
3234                buf.append(" abi=");
3235                buf.append(requiredAbi);
3236            }
3237            Slog.i(TAG, buf.toString());
3238            app.setPid(startResult.pid);
3239            app.usingWrapper = startResult.usingWrapper;
3240            app.removed = false;
3241            app.killed = false;
3242            app.killedByAm = false;
3243            checkTime(startTime, "startProcess: starting to update pids map");
3244            synchronized (mPidsSelfLocked) {
3245                this.mPidsSelfLocked.put(startResult.pid, app);
3246                if (isActivityProcess) {
3247                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3248                    msg.obj = app;
3249                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3250                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3251                }
3252            }
3253            checkTime(startTime, "startProcess: done updating pids map");
3254        } catch (RuntimeException e) {
3255            // XXX do better error recovery.
3256            app.setPid(0);
3257            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3258            if (app.isolated) {
3259                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3260            }
3261            Slog.e(TAG, "Failure starting process " + app.processName, e);
3262        }
3263    }
3264
3265    void updateUsageStats(ActivityRecord component, boolean resumed) {
3266        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3267        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3268        if (resumed) {
3269            if (mUsageStatsService != null) {
3270                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3271                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3272            }
3273            synchronized (stats) {
3274                stats.noteActivityResumedLocked(component.app.uid);
3275            }
3276        } else {
3277            if (mUsageStatsService != null) {
3278                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3279                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3280            }
3281            synchronized (stats) {
3282                stats.noteActivityPausedLocked(component.app.uid);
3283            }
3284        }
3285    }
3286
3287    Intent getHomeIntent() {
3288        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3289        intent.setComponent(mTopComponent);
3290        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3291            intent.addCategory(Intent.CATEGORY_HOME);
3292        }
3293        return intent;
3294    }
3295
3296    boolean startHomeActivityLocked(int userId) {
3297        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3298                && mTopAction == null) {
3299            // We are running in factory test mode, but unable to find
3300            // the factory test app, so just sit around displaying the
3301            // error message and don't try to start anything.
3302            return false;
3303        }
3304        Intent intent = getHomeIntent();
3305        ActivityInfo aInfo =
3306            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3307        if (aInfo != null) {
3308            intent.setComponent(new ComponentName(
3309                    aInfo.applicationInfo.packageName, aInfo.name));
3310            // Don't do this if the home app is currently being
3311            // instrumented.
3312            aInfo = new ActivityInfo(aInfo);
3313            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3314            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3315                    aInfo.applicationInfo.uid, true);
3316            if (app == null || app.instrumentationClass == null) {
3317                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3318                mStackSupervisor.startHomeActivity(intent, aInfo);
3319            }
3320        }
3321
3322        return true;
3323    }
3324
3325    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3326        ActivityInfo ai = null;
3327        ComponentName comp = intent.getComponent();
3328        try {
3329            if (comp != null) {
3330                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3331            } else {
3332                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3333                        intent,
3334                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3335                            flags, userId);
3336
3337                if (info != null) {
3338                    ai = info.activityInfo;
3339                }
3340            }
3341        } catch (RemoteException e) {
3342            // ignore
3343        }
3344
3345        return ai;
3346    }
3347
3348    /**
3349     * Starts the "new version setup screen" if appropriate.
3350     */
3351    void startSetupActivityLocked() {
3352        // Only do this once per boot.
3353        if (mCheckedForSetup) {
3354            return;
3355        }
3356
3357        // We will show this screen if the current one is a different
3358        // version than the last one shown, and we are not running in
3359        // low-level factory test mode.
3360        final ContentResolver resolver = mContext.getContentResolver();
3361        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3362                Settings.Global.getInt(resolver,
3363                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3364            mCheckedForSetup = true;
3365
3366            // See if we should be showing the platform update setup UI.
3367            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3368            List<ResolveInfo> ris = mContext.getPackageManager()
3369                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3370
3371            // We don't allow third party apps to replace this.
3372            ResolveInfo ri = null;
3373            for (int i=0; ris != null && i<ris.size(); i++) {
3374                if ((ris.get(i).activityInfo.applicationInfo.flags
3375                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3376                    ri = ris.get(i);
3377                    break;
3378                }
3379            }
3380
3381            if (ri != null) {
3382                String vers = ri.activityInfo.metaData != null
3383                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3384                        : null;
3385                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3386                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3387                            Intent.METADATA_SETUP_VERSION);
3388                }
3389                String lastVers = Settings.Secure.getString(
3390                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3391                if (vers != null && !vers.equals(lastVers)) {
3392                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3393                    intent.setComponent(new ComponentName(
3394                            ri.activityInfo.packageName, ri.activityInfo.name));
3395                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3396                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3397                            null);
3398                }
3399            }
3400        }
3401    }
3402
3403    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3404        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3405    }
3406
3407    void enforceNotIsolatedCaller(String caller) {
3408        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3409            throw new SecurityException("Isolated process not allowed to call " + caller);
3410        }
3411    }
3412
3413    void enforceShellRestriction(String restriction, int userHandle) {
3414        if (Binder.getCallingUid() == Process.SHELL_UID) {
3415            if (userHandle < 0
3416                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3417                throw new SecurityException("Shell does not have permission to access user "
3418                        + userHandle);
3419            }
3420        }
3421    }
3422
3423    @Override
3424    public int getFrontActivityScreenCompatMode() {
3425        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3426        synchronized (this) {
3427            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3428        }
3429    }
3430
3431    @Override
3432    public void setFrontActivityScreenCompatMode(int mode) {
3433        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3434                "setFrontActivityScreenCompatMode");
3435        synchronized (this) {
3436            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3437        }
3438    }
3439
3440    @Override
3441    public int getPackageScreenCompatMode(String packageName) {
3442        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3443        synchronized (this) {
3444            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3445        }
3446    }
3447
3448    @Override
3449    public void setPackageScreenCompatMode(String packageName, int mode) {
3450        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3451                "setPackageScreenCompatMode");
3452        synchronized (this) {
3453            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3454        }
3455    }
3456
3457    @Override
3458    public boolean getPackageAskScreenCompat(String packageName) {
3459        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3460        synchronized (this) {
3461            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3462        }
3463    }
3464
3465    @Override
3466    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3467        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3468                "setPackageAskScreenCompat");
3469        synchronized (this) {
3470            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3471        }
3472    }
3473
3474    private void dispatchProcessesChanged() {
3475        int N;
3476        synchronized (this) {
3477            N = mPendingProcessChanges.size();
3478            if (mActiveProcessChanges.length < N) {
3479                mActiveProcessChanges = new ProcessChangeItem[N];
3480            }
3481            mPendingProcessChanges.toArray(mActiveProcessChanges);
3482            mAvailProcessChanges.addAll(mPendingProcessChanges);
3483            mPendingProcessChanges.clear();
3484            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3485        }
3486
3487        int i = mProcessObservers.beginBroadcast();
3488        while (i > 0) {
3489            i--;
3490            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3491            if (observer != null) {
3492                try {
3493                    for (int j=0; j<N; j++) {
3494                        ProcessChangeItem item = mActiveProcessChanges[j];
3495                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3496                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3497                                    + item.pid + " uid=" + item.uid + ": "
3498                                    + item.foregroundActivities);
3499                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3500                                    item.foregroundActivities);
3501                        }
3502                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3503                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3504                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3505                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3506                        }
3507                    }
3508                } catch (RemoteException e) {
3509                }
3510            }
3511        }
3512        mProcessObservers.finishBroadcast();
3513    }
3514
3515    private void dispatchProcessDied(int pid, int uid) {
3516        int i = mProcessObservers.beginBroadcast();
3517        while (i > 0) {
3518            i--;
3519            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3520            if (observer != null) {
3521                try {
3522                    observer.onProcessDied(pid, uid);
3523                } catch (RemoteException e) {
3524                }
3525            }
3526        }
3527        mProcessObservers.finishBroadcast();
3528    }
3529
3530    @Override
3531    public final int startActivity(IApplicationThread caller, String callingPackage,
3532            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3533            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3534        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3535            resultWho, requestCode, startFlags, profilerInfo, options,
3536            UserHandle.getCallingUserId());
3537    }
3538
3539    @Override
3540    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3543        enforceNotIsolatedCaller("startActivity");
3544        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3545                false, ALLOW_FULL_ONLY, "startActivity", null);
3546        // TODO: Switch to user app stacks here.
3547        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3548                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3549                profilerInfo, null, null, options, userId, null, null);
3550    }
3551
3552    @Override
3553    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3554            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3555            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3556
3557        // This is very dangerous -- it allows you to perform a start activity (including
3558        // permission grants) as any app that may launch one of your own activities.  So
3559        // we will only allow this to be done from activities that are part of the core framework,
3560        // and then only when they are running as the system.
3561        final ActivityRecord sourceRecord;
3562        final int targetUid;
3563        final String targetPackage;
3564        synchronized (this) {
3565            if (resultTo == null) {
3566                throw new SecurityException("Must be called from an activity");
3567            }
3568            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3569            if (sourceRecord == null) {
3570                throw new SecurityException("Called with bad activity token: " + resultTo);
3571            }
3572            if (!sourceRecord.info.packageName.equals("android")) {
3573                throw new SecurityException(
3574                        "Must be called from an activity that is declared in the android package");
3575            }
3576            if (sourceRecord.app == null) {
3577                throw new SecurityException("Called without a process attached to activity");
3578            }
3579            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3580                // This is still okay, as long as this activity is running under the
3581                // uid of the original calling activity.
3582                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3583                    throw new SecurityException(
3584                            "Calling activity in uid " + sourceRecord.app.uid
3585                                    + " must be system uid or original calling uid "
3586                                    + sourceRecord.launchedFromUid);
3587                }
3588            }
3589            targetUid = sourceRecord.launchedFromUid;
3590            targetPackage = sourceRecord.launchedFromPackage;
3591        }
3592
3593        // TODO: Switch to user app stacks here.
3594        try {
3595            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3596                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3597                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3598            return ret;
3599        } catch (SecurityException e) {
3600            // XXX need to figure out how to propagate to original app.
3601            // A SecurityException here is generally actually a fault of the original
3602            // calling activity (such as a fairly granting permissions), so propagate it
3603            // back to them.
3604            /*
3605            StringBuilder msg = new StringBuilder();
3606            msg.append("While launching");
3607            msg.append(intent.toString());
3608            msg.append(": ");
3609            msg.append(e.getMessage());
3610            */
3611            throw e;
3612        }
3613    }
3614
3615    @Override
3616    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3617            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3618            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3619        enforceNotIsolatedCaller("startActivityAndWait");
3620        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3621                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3622        WaitResult res = new WaitResult();
3623        // TODO: Switch to user app stacks here.
3624        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3625                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3626                options, userId, null, null);
3627        return res;
3628    }
3629
3630    @Override
3631    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3632            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3633            int startFlags, Configuration config, Bundle options, int userId) {
3634        enforceNotIsolatedCaller("startActivityWithConfig");
3635        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3636                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3637        // TODO: Switch to user app stacks here.
3638        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3639                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3640                null, null, config, options, userId, null, null);
3641        return ret;
3642    }
3643
3644    @Override
3645    public int startActivityIntentSender(IApplicationThread caller,
3646            IntentSender intent, Intent fillInIntent, String resolvedType,
3647            IBinder resultTo, String resultWho, int requestCode,
3648            int flagsMask, int flagsValues, Bundle options) {
3649        enforceNotIsolatedCaller("startActivityIntentSender");
3650        // Refuse possible leaked file descriptors
3651        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3652            throw new IllegalArgumentException("File descriptors passed in Intent");
3653        }
3654
3655        IIntentSender sender = intent.getTarget();
3656        if (!(sender instanceof PendingIntentRecord)) {
3657            throw new IllegalArgumentException("Bad PendingIntent object");
3658        }
3659
3660        PendingIntentRecord pir = (PendingIntentRecord)sender;
3661
3662        synchronized (this) {
3663            // If this is coming from the currently resumed activity, it is
3664            // effectively saying that app switches are allowed at this point.
3665            final ActivityStack stack = getFocusedStack();
3666            if (stack.mResumedActivity != null &&
3667                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3668                mAppSwitchesAllowedTime = 0;
3669            }
3670        }
3671        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3672                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3673        return ret;
3674    }
3675
3676    @Override
3677    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3678            Intent intent, String resolvedType, IVoiceInteractionSession session,
3679            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3680            Bundle options, int userId) {
3681        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3682                != PackageManager.PERMISSION_GRANTED) {
3683            String msg = "Permission Denial: startVoiceActivity() from pid="
3684                    + Binder.getCallingPid()
3685                    + ", uid=" + Binder.getCallingUid()
3686                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3687            Slog.w(TAG, msg);
3688            throw new SecurityException(msg);
3689        }
3690        if (session == null || interactor == null) {
3691            throw new NullPointerException("null session or interactor");
3692        }
3693        userId = handleIncomingUser(callingPid, callingUid, userId,
3694                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3695        // TODO: Switch to user app stacks here.
3696        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3697                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3698                null, options, userId, null, null);
3699    }
3700
3701    @Override
3702    public boolean startNextMatchingActivity(IBinder callingActivity,
3703            Intent intent, Bundle options) {
3704        // Refuse possible leaked file descriptors
3705        if (intent != null && intent.hasFileDescriptors() == true) {
3706            throw new IllegalArgumentException("File descriptors passed in Intent");
3707        }
3708
3709        synchronized (this) {
3710            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3711            if (r == null) {
3712                ActivityOptions.abort(options);
3713                return false;
3714            }
3715            if (r.app == null || r.app.thread == null) {
3716                // The caller is not running...  d'oh!
3717                ActivityOptions.abort(options);
3718                return false;
3719            }
3720            intent = new Intent(intent);
3721            // The caller is not allowed to change the data.
3722            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3723            // And we are resetting to find the next component...
3724            intent.setComponent(null);
3725
3726            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3727
3728            ActivityInfo aInfo = null;
3729            try {
3730                List<ResolveInfo> resolves =
3731                    AppGlobals.getPackageManager().queryIntentActivities(
3732                            intent, r.resolvedType,
3733                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3734                            UserHandle.getCallingUserId());
3735
3736                // Look for the original activity in the list...
3737                final int N = resolves != null ? resolves.size() : 0;
3738                for (int i=0; i<N; i++) {
3739                    ResolveInfo rInfo = resolves.get(i);
3740                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3741                            && rInfo.activityInfo.name.equals(r.info.name)) {
3742                        // We found the current one...  the next matching is
3743                        // after it.
3744                        i++;
3745                        if (i<N) {
3746                            aInfo = resolves.get(i).activityInfo;
3747                        }
3748                        if (debug) {
3749                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3750                                    + "/" + r.info.name);
3751                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3752                                    + "/" + aInfo.name);
3753                        }
3754                        break;
3755                    }
3756                }
3757            } catch (RemoteException e) {
3758            }
3759
3760            if (aInfo == null) {
3761                // Nobody who is next!
3762                ActivityOptions.abort(options);
3763                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3764                return false;
3765            }
3766
3767            intent.setComponent(new ComponentName(
3768                    aInfo.applicationInfo.packageName, aInfo.name));
3769            intent.setFlags(intent.getFlags()&~(
3770                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3771                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3772                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3773                    Intent.FLAG_ACTIVITY_NEW_TASK));
3774
3775            // Okay now we need to start the new activity, replacing the
3776            // currently running activity.  This is a little tricky because
3777            // we want to start the new one as if the current one is finished,
3778            // but not finish the current one first so that there is no flicker.
3779            // And thus...
3780            final boolean wasFinishing = r.finishing;
3781            r.finishing = true;
3782
3783            // Propagate reply information over to the new activity.
3784            final ActivityRecord resultTo = r.resultTo;
3785            final String resultWho = r.resultWho;
3786            final int requestCode = r.requestCode;
3787            r.resultTo = null;
3788            if (resultTo != null) {
3789                resultTo.removeResultsLocked(r, resultWho, requestCode);
3790            }
3791
3792            final long origId = Binder.clearCallingIdentity();
3793            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3794                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3795                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3796                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3797            Binder.restoreCallingIdentity(origId);
3798
3799            r.finishing = wasFinishing;
3800            if (res != ActivityManager.START_SUCCESS) {
3801                return false;
3802            }
3803            return true;
3804        }
3805    }
3806
3807    @Override
3808    public final int startActivityFromRecents(int taskId, Bundle options) {
3809        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3810            String msg = "Permission Denial: startActivityFromRecents called without " +
3811                    START_TASKS_FROM_RECENTS;
3812            Slog.w(TAG, msg);
3813            throw new SecurityException(msg);
3814        }
3815        return startActivityFromRecentsInner(taskId, options);
3816    }
3817
3818    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3819        final TaskRecord task;
3820        final int callingUid;
3821        final String callingPackage;
3822        final Intent intent;
3823        final int userId;
3824        synchronized (this) {
3825            task = recentTaskForIdLocked(taskId);
3826            if (task == null) {
3827                throw new IllegalArgumentException("Task " + taskId + " not found.");
3828            }
3829            callingUid = task.mCallingUid;
3830            callingPackage = task.mCallingPackage;
3831            intent = task.intent;
3832            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3833            userId = task.userId;
3834        }
3835        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3836                options, userId, null, task);
3837    }
3838
3839    final int startActivityInPackage(int uid, String callingPackage,
3840            Intent intent, String resolvedType, IBinder resultTo,
3841            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3842            IActivityContainer container, TaskRecord inTask) {
3843
3844        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3845                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3846
3847        // TODO: Switch to user app stacks here.
3848        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3849                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3850                null, null, null, options, userId, container, inTask);
3851        return ret;
3852    }
3853
3854    @Override
3855    public final int startActivities(IApplicationThread caller, String callingPackage,
3856            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3857            int userId) {
3858        enforceNotIsolatedCaller("startActivities");
3859        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3860                false, ALLOW_FULL_ONLY, "startActivity", null);
3861        // TODO: Switch to user app stacks here.
3862        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3863                resolvedTypes, resultTo, options, userId);
3864        return ret;
3865    }
3866
3867    final int startActivitiesInPackage(int uid, String callingPackage,
3868            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3869            Bundle options, int userId) {
3870
3871        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3872                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3873        // TODO: Switch to user app stacks here.
3874        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3875                resultTo, options, userId);
3876        return ret;
3877    }
3878
3879    //explicitly remove thd old information in mRecentTasks when removing existing user.
3880    private void removeRecentTasksForUserLocked(int userId) {
3881        if(userId <= 0) {
3882            Slog.i(TAG, "Can't remove recent task on user " + userId);
3883            return;
3884        }
3885
3886        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3887            TaskRecord tr = mRecentTasks.get(i);
3888            if (tr.userId == userId) {
3889                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3890                        + " when finishing user" + userId);
3891                mRecentTasks.remove(i);
3892                tr.removedFromRecents(mTaskPersister);
3893            }
3894        }
3895
3896        // Remove tasks from persistent storage.
3897        mTaskPersister.wakeup(null, true);
3898    }
3899
3900    // Sort by taskId
3901    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3902        @Override
3903        public int compare(TaskRecord lhs, TaskRecord rhs) {
3904            return rhs.taskId - lhs.taskId;
3905        }
3906    };
3907
3908    // Extract the affiliates of the chain containing mRecentTasks[start].
3909    private int processNextAffiliateChain(int start) {
3910        final TaskRecord startTask = mRecentTasks.get(start);
3911        final int affiliateId = startTask.mAffiliatedTaskId;
3912
3913        // Quick identification of isolated tasks. I.e. those not launched behind.
3914        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3915                startTask.mNextAffiliate == null) {
3916            // There is still a slim chance that there are other tasks that point to this task
3917            // and that the chain is so messed up that this task no longer points to them but
3918            // the gain of this optimization outweighs the risk.
3919            startTask.inRecents = true;
3920            return start + 1;
3921        }
3922
3923        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3924        mTmpRecents.clear();
3925        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3926            final TaskRecord task = mRecentTasks.get(i);
3927            if (task.mAffiliatedTaskId == affiliateId) {
3928                mRecentTasks.remove(i);
3929                mTmpRecents.add(task);
3930            }
3931        }
3932
3933        // Sort them all by taskId. That is the order they were create in and that order will
3934        // always be correct.
3935        Collections.sort(mTmpRecents, mTaskRecordComparator);
3936
3937        // Go through and fix up the linked list.
3938        // The first one is the end of the chain and has no next.
3939        final TaskRecord first = mTmpRecents.get(0);
3940        first.inRecents = true;
3941        if (first.mNextAffiliate != null) {
3942            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3943            first.setNextAffiliate(null);
3944            mTaskPersister.wakeup(first, false);
3945        }
3946        // Everything in the middle is doubly linked from next to prev.
3947        final int tmpSize = mTmpRecents.size();
3948        for (int i = 0; i < tmpSize - 1; ++i) {
3949            final TaskRecord next = mTmpRecents.get(i);
3950            final TaskRecord prev = mTmpRecents.get(i + 1);
3951            if (next.mPrevAffiliate != prev) {
3952                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3953                        " setting prev=" + prev);
3954                next.setPrevAffiliate(prev);
3955                mTaskPersister.wakeup(next, false);
3956            }
3957            if (prev.mNextAffiliate != next) {
3958                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3959                        " setting next=" + next);
3960                prev.setNextAffiliate(next);
3961                mTaskPersister.wakeup(prev, false);
3962            }
3963            prev.inRecents = true;
3964        }
3965        // The last one is the beginning of the list and has no prev.
3966        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3967        if (last.mPrevAffiliate != null) {
3968            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3969            last.setPrevAffiliate(null);
3970            mTaskPersister.wakeup(last, false);
3971        }
3972
3973        // Insert the group back into mRecentTasks at start.
3974        mRecentTasks.addAll(start, mTmpRecents);
3975
3976        // Let the caller know where we left off.
3977        return start + tmpSize;
3978    }
3979
3980    /**
3981     * Update the recent tasks lists: make sure tasks should still be here (their
3982     * applications / activities still exist), update their availability, fixup ordering
3983     * of affiliations.
3984     */
3985    void cleanupRecentTasksLocked(int userId) {
3986        if (mRecentTasks == null) {
3987            // Happens when called from the packagemanager broadcast before boot.
3988            return;
3989        }
3990
3991        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3992        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3993        final IPackageManager pm = AppGlobals.getPackageManager();
3994        final ActivityInfo dummyAct = new ActivityInfo();
3995        final ApplicationInfo dummyApp = new ApplicationInfo();
3996
3997        int N = mRecentTasks.size();
3998
3999        int[] users = userId == UserHandle.USER_ALL
4000                ? getUsersLocked() : new int[] { userId };
4001        for (int user : users) {
4002            for (int i = 0; i < N; i++) {
4003                TaskRecord task = mRecentTasks.get(i);
4004                if (task.userId != user) {
4005                    // Only look at tasks for the user ID of interest.
4006                    continue;
4007                }
4008                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4009                    // This situation is broken, and we should just get rid of it now.
4010                    mRecentTasks.remove(i);
4011                    task.removedFromRecents(mTaskPersister);
4012                    i--;
4013                    N--;
4014                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4015                    continue;
4016                }
4017                // Check whether this activity is currently available.
4018                if (task.realActivity != null) {
4019                    ActivityInfo ai = availActCache.get(task.realActivity);
4020                    if (ai == null) {
4021                        try {
4022                            ai = pm.getActivityInfo(task.realActivity,
4023                                    PackageManager.GET_UNINSTALLED_PACKAGES
4024                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4025                        } catch (RemoteException e) {
4026                            // Will never happen.
4027                            continue;
4028                        }
4029                        if (ai == null) {
4030                            ai = dummyAct;
4031                        }
4032                        availActCache.put(task.realActivity, ai);
4033                    }
4034                    if (ai == dummyAct) {
4035                        // This could be either because the activity no longer exists, or the
4036                        // app is temporarily gone.  For the former we want to remove the recents
4037                        // entry; for the latter we want to mark it as unavailable.
4038                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4039                        if (app == null) {
4040                            try {
4041                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4042                                        PackageManager.GET_UNINSTALLED_PACKAGES
4043                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4044                            } catch (RemoteException e) {
4045                                // Will never happen.
4046                                continue;
4047                            }
4048                            if (app == null) {
4049                                app = dummyApp;
4050                            }
4051                            availAppCache.put(task.realActivity.getPackageName(), app);
4052                        }
4053                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4054                            // Doesn't exist any more!  Good-bye.
4055                            mRecentTasks.remove(i);
4056                            task.removedFromRecents(mTaskPersister);
4057                            i--;
4058                            N--;
4059                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4060                            continue;
4061                        } else {
4062                            // Otherwise just not available for now.
4063                            if (task.isAvailable) {
4064                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4065                                        + task);
4066                            }
4067                            task.isAvailable = false;
4068                        }
4069                    } else {
4070                        if (!ai.enabled || !ai.applicationInfo.enabled
4071                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4072                            if (task.isAvailable) {
4073                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4074                                        + task + " (enabled=" + ai.enabled + "/"
4075                                        + ai.applicationInfo.enabled +  " flags="
4076                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4077                            }
4078                            task.isAvailable = false;
4079                        } else {
4080                            if (!task.isAvailable) {
4081                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4082                                        + task);
4083                            }
4084                            task.isAvailable = true;
4085                        }
4086                    }
4087                }
4088            }
4089        }
4090
4091        // Verify the affiliate chain for each task.
4092        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4093        }
4094
4095        mTmpRecents.clear();
4096        // mRecentTasks is now in sorted, affiliated order.
4097    }
4098
4099    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4100        int N = mRecentTasks.size();
4101        TaskRecord top = task;
4102        int topIndex = taskIndex;
4103        while (top.mNextAffiliate != null && topIndex > 0) {
4104            top = top.mNextAffiliate;
4105            topIndex--;
4106        }
4107        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4108                + topIndex + " from intial " + taskIndex);
4109        // Find the end of the chain, doing a sanity check along the way.
4110        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4111        int endIndex = topIndex;
4112        TaskRecord prev = top;
4113        while (endIndex < N) {
4114            TaskRecord cur = mRecentTasks.get(endIndex);
4115            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4116                    + endIndex + " " + cur);
4117            if (cur == top) {
4118                // Verify start of the chain.
4119                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4120                    Slog.wtf(TAG, "Bad chain @" + endIndex
4121                            + ": first task has next affiliate: " + prev);
4122                    sane = false;
4123                    break;
4124                }
4125            } else {
4126                // Verify middle of the chain's next points back to the one before.
4127                if (cur.mNextAffiliate != prev
4128                        || cur.mNextAffiliateTaskId != prev.taskId) {
4129                    Slog.wtf(TAG, "Bad chain @" + endIndex
4130                            + ": middle task " + cur + " @" + endIndex
4131                            + " has bad next affiliate "
4132                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4133                            + ", expected " + prev);
4134                    sane = false;
4135                    break;
4136                }
4137            }
4138            if (cur.mPrevAffiliateTaskId == -1) {
4139                // Chain ends here.
4140                if (cur.mPrevAffiliate != null) {
4141                    Slog.wtf(TAG, "Bad chain @" + endIndex
4142                            + ": last task " + cur + " has previous affiliate "
4143                            + cur.mPrevAffiliate);
4144                    sane = false;
4145                }
4146                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4147                break;
4148            } else {
4149                // Verify middle of the chain's prev points to a valid item.
4150                if (cur.mPrevAffiliate == null) {
4151                    Slog.wtf(TAG, "Bad chain @" + endIndex
4152                            + ": task " + cur + " has previous affiliate "
4153                            + cur.mPrevAffiliate + " but should be id "
4154                            + cur.mPrevAffiliate);
4155                    sane = false;
4156                    break;
4157                }
4158            }
4159            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4160                Slog.wtf(TAG, "Bad chain @" + endIndex
4161                        + ": task " + cur + " has affiliated id "
4162                        + cur.mAffiliatedTaskId + " but should be "
4163                        + task.mAffiliatedTaskId);
4164                sane = false;
4165                break;
4166            }
4167            prev = cur;
4168            endIndex++;
4169            if (endIndex >= N) {
4170                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4171                        + ": last task " + prev);
4172                sane = false;
4173                break;
4174            }
4175        }
4176        if (sane) {
4177            if (endIndex < taskIndex) {
4178                Slog.wtf(TAG, "Bad chain @" + endIndex
4179                        + ": did not extend to task " + task + " @" + taskIndex);
4180                sane = false;
4181            }
4182        }
4183        if (sane) {
4184            // All looks good, we can just move all of the affiliated tasks
4185            // to the top.
4186            for (int i=topIndex; i<=endIndex; i++) {
4187                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4188                        + " from " + i + " to " + (i-topIndex));
4189                TaskRecord cur = mRecentTasks.remove(i);
4190                mRecentTasks.add(i-topIndex, cur);
4191            }
4192            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4193                    + " to " + endIndex);
4194            return true;
4195        }
4196
4197        // Whoops, couldn't do it.
4198        return false;
4199    }
4200
4201    final void addRecentTaskLocked(TaskRecord task) {
4202        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4203                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4204
4205        int N = mRecentTasks.size();
4206        // Quick case: check if the top-most recent task is the same.
4207        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4208            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4209            return;
4210        }
4211        // Another quick case: check if this is part of a set of affiliated
4212        // tasks that are at the top.
4213        if (isAffiliated && N > 0 && task.inRecents
4214                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4215            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4216                    + " at top when adding " + task);
4217            return;
4218        }
4219        // Another quick case: never add voice sessions.
4220        if (task.voiceSession != null) {
4221            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4222            return;
4223        }
4224
4225        boolean needAffiliationFix = false;
4226
4227        // Slightly less quick case: the task is already in recents, so all we need
4228        // to do is move it.
4229        if (task.inRecents) {
4230            int taskIndex = mRecentTasks.indexOf(task);
4231            if (taskIndex >= 0) {
4232                if (!isAffiliated) {
4233                    // Simple case: this is not an affiliated task, so we just move it to the front.
4234                    mRecentTasks.remove(taskIndex);
4235                    mRecentTasks.add(0, task);
4236                    notifyTaskPersisterLocked(task, false);
4237                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4238                            + " from " + taskIndex);
4239                    return;
4240                } else {
4241                    // More complicated: need to keep all affiliated tasks together.
4242                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4243                        // All went well.
4244                        return;
4245                    }
4246
4247                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4248                    // everything and then go through our general path of adding a new task.
4249                    needAffiliationFix = true;
4250                }
4251            } else {
4252                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4253                needAffiliationFix = true;
4254            }
4255        }
4256
4257        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4258        trimRecentsForTask(task, true);
4259
4260        N = mRecentTasks.size();
4261        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4262            final TaskRecord tr = mRecentTasks.remove(N - 1);
4263            tr.removedFromRecents(mTaskPersister);
4264            N--;
4265        }
4266        task.inRecents = true;
4267        if (!isAffiliated || needAffiliationFix) {
4268            // If this is a simple non-affiliated task, or we had some failure trying to
4269            // handle it as part of an affilated task, then just place it at the top.
4270            mRecentTasks.add(0, task);
4271        } else if (isAffiliated) {
4272            // If this is a new affiliated task, then move all of the affiliated tasks
4273            // to the front and insert this new one.
4274            TaskRecord other = task.mNextAffiliate;
4275            if (other == null) {
4276                other = task.mPrevAffiliate;
4277            }
4278            if (other != null) {
4279                int otherIndex = mRecentTasks.indexOf(other);
4280                if (otherIndex >= 0) {
4281                    // Insert new task at appropriate location.
4282                    int taskIndex;
4283                    if (other == task.mNextAffiliate) {
4284                        // We found the index of our next affiliation, which is who is
4285                        // before us in the list, so add after that point.
4286                        taskIndex = otherIndex+1;
4287                    } else {
4288                        // We found the index of our previous affiliation, which is who is
4289                        // after us in the list, so add at their position.
4290                        taskIndex = otherIndex;
4291                    }
4292                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4293                            + taskIndex + ": " + task);
4294                    mRecentTasks.add(taskIndex, task);
4295
4296                    // Now move everything to the front.
4297                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4298                        // All went well.
4299                        return;
4300                    }
4301
4302                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4303                    // everything and then go through our general path of adding a new task.
4304                    needAffiliationFix = true;
4305                } else {
4306                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4307                            + other);
4308                    needAffiliationFix = true;
4309                }
4310            } else {
4311                if (DEBUG_RECENTS) Slog.d(TAG,
4312                        "addRecent: adding affiliated task without next/prev:" + task);
4313                needAffiliationFix = true;
4314            }
4315        }
4316        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4317
4318        if (needAffiliationFix) {
4319            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4320            cleanupRecentTasksLocked(task.userId);
4321        }
4322    }
4323
4324    /**
4325     * If needed, remove oldest existing entries in recents that are for the same kind
4326     * of task as the given one.
4327     */
4328    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4329        int N = mRecentTasks.size();
4330        final Intent intent = task.intent;
4331        final boolean document = intent != null && intent.isDocument();
4332
4333        int maxRecents = task.maxRecents - 1;
4334        for (int i=0; i<N; i++) {
4335            final TaskRecord tr = mRecentTasks.get(i);
4336            if (task != tr) {
4337                if (task.userId != tr.userId) {
4338                    continue;
4339                }
4340                if (i > MAX_RECENT_BITMAPS) {
4341                    tr.freeLastThumbnail();
4342                }
4343                final Intent trIntent = tr.intent;
4344                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4345                    (intent == null || !intent.filterEquals(trIntent))) {
4346                    continue;
4347                }
4348                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4349                if (document && trIsDocument) {
4350                    // These are the same document activity (not necessarily the same doc).
4351                    if (maxRecents > 0) {
4352                        --maxRecents;
4353                        continue;
4354                    }
4355                    // Hit the maximum number of documents for this task. Fall through
4356                    // and remove this document from recents.
4357                } else if (document || trIsDocument) {
4358                    // Only one of these is a document. Not the droid we're looking for.
4359                    continue;
4360                }
4361            }
4362
4363            if (!doTrim) {
4364                // If the caller is not actually asking for a trim, just tell them we reached
4365                // a point where the trim would happen.
4366                return i;
4367            }
4368
4369            // Either task and tr are the same or, their affinities match or their intents match
4370            // and neither of them is a document, or they are documents using the same activity
4371            // and their maxRecents has been reached.
4372            tr.disposeThumbnail();
4373            mRecentTasks.remove(i);
4374            if (task != tr) {
4375                tr.removedFromRecents(mTaskPersister);
4376            }
4377            i--;
4378            N--;
4379            if (task.intent == null) {
4380                // If the new recent task we are adding is not fully
4381                // specified, then replace it with the existing recent task.
4382                task = tr;
4383            }
4384            notifyTaskPersisterLocked(tr, false);
4385        }
4386
4387        return -1;
4388    }
4389
4390    @Override
4391    public void reportActivityFullyDrawn(IBinder token) {
4392        synchronized (this) {
4393            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4394            if (r == null) {
4395                return;
4396            }
4397            r.reportFullyDrawnLocked();
4398        }
4399    }
4400
4401    @Override
4402    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4403        synchronized (this) {
4404            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4405            if (r == null) {
4406                return;
4407            }
4408            final long origId = Binder.clearCallingIdentity();
4409            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4410            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4411                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4412            if (config != null) {
4413                r.frozenBeforeDestroy = true;
4414                if (!updateConfigurationLocked(config, r, false, false)) {
4415                    mStackSupervisor.resumeTopActivitiesLocked();
4416                }
4417            }
4418            Binder.restoreCallingIdentity(origId);
4419        }
4420    }
4421
4422    @Override
4423    public int getRequestedOrientation(IBinder token) {
4424        synchronized (this) {
4425            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4426            if (r == null) {
4427                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4428            }
4429            return mWindowManager.getAppOrientation(r.appToken);
4430        }
4431    }
4432
4433    /**
4434     * This is the internal entry point for handling Activity.finish().
4435     *
4436     * @param token The Binder token referencing the Activity we want to finish.
4437     * @param resultCode Result code, if any, from this Activity.
4438     * @param resultData Result data (Intent), if any, from this Activity.
4439     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4440     *            the root Activity in the task.
4441     *
4442     * @return Returns true if the activity successfully finished, or false if it is still running.
4443     */
4444    @Override
4445    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4446            boolean finishTask) {
4447        // Refuse possible leaked file descriptors
4448        if (resultData != null && resultData.hasFileDescriptors() == true) {
4449            throw new IllegalArgumentException("File descriptors passed in Intent");
4450        }
4451
4452        synchronized(this) {
4453            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454            if (r == null) {
4455                return true;
4456            }
4457            // Keep track of the root activity of the task before we finish it
4458            TaskRecord tr = r.task;
4459            ActivityRecord rootR = tr.getRootActivity();
4460            // Do not allow task to finish in Lock Task mode.
4461            if (tr == mStackSupervisor.mLockTaskModeTask) {
4462                if (rootR == r) {
4463                    mStackSupervisor.showLockTaskToast();
4464                    return false;
4465                }
4466            }
4467            if (mController != null) {
4468                // Find the first activity that is not finishing.
4469                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4470                if (next != null) {
4471                    // ask watcher if this is allowed
4472                    boolean resumeOK = true;
4473                    try {
4474                        resumeOK = mController.activityResuming(next.packageName);
4475                    } catch (RemoteException e) {
4476                        mController = null;
4477                        Watchdog.getInstance().setActivityController(null);
4478                    }
4479
4480                    if (!resumeOK) {
4481                        return false;
4482                    }
4483                }
4484            }
4485            final long origId = Binder.clearCallingIdentity();
4486            try {
4487                boolean res;
4488                if (finishTask && r == rootR) {
4489                    // If requested, remove the task that is associated to this activity only if it
4490                    // was the root activity in the task.  The result code and data is ignored because
4491                    // we don't support returning them across task boundaries.
4492                    res = removeTaskByIdLocked(tr.taskId, 0);
4493                } else {
4494                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4495                            resultData, "app-request", true);
4496                }
4497                return res;
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public final void finishHeavyWeightApp() {
4506        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4507                != PackageManager.PERMISSION_GRANTED) {
4508            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4509                    + Binder.getCallingPid()
4510                    + ", uid=" + Binder.getCallingUid()
4511                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4512            Slog.w(TAG, msg);
4513            throw new SecurityException(msg);
4514        }
4515
4516        synchronized(this) {
4517            if (mHeavyWeightProcess == null) {
4518                return;
4519            }
4520
4521            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4522                    mHeavyWeightProcess.activities);
4523            for (int i=0; i<activities.size(); i++) {
4524                ActivityRecord r = activities.get(i);
4525                if (!r.finishing) {
4526                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4527                            null, "finish-heavy", true);
4528                }
4529            }
4530
4531            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4532                    mHeavyWeightProcess.userId, 0));
4533            mHeavyWeightProcess = null;
4534        }
4535    }
4536
4537    @Override
4538    public void crashApplication(int uid, int initialPid, String packageName,
4539            String message) {
4540        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4541                != PackageManager.PERMISSION_GRANTED) {
4542            String msg = "Permission Denial: crashApplication() from pid="
4543                    + Binder.getCallingPid()
4544                    + ", uid=" + Binder.getCallingUid()
4545                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4546            Slog.w(TAG, msg);
4547            throw new SecurityException(msg);
4548        }
4549
4550        synchronized(this) {
4551            ProcessRecord proc = null;
4552
4553            // Figure out which process to kill.  We don't trust that initialPid
4554            // still has any relation to current pids, so must scan through the
4555            // list.
4556            synchronized (mPidsSelfLocked) {
4557                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4558                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4559                    if (p.uid != uid) {
4560                        continue;
4561                    }
4562                    if (p.pid == initialPid) {
4563                        proc = p;
4564                        break;
4565                    }
4566                    if (p.pkgList.containsKey(packageName)) {
4567                        proc = p;
4568                    }
4569                }
4570            }
4571
4572            if (proc == null) {
4573                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4574                        + " initialPid=" + initialPid
4575                        + " packageName=" + packageName);
4576                return;
4577            }
4578
4579            if (proc.thread != null) {
4580                if (proc.pid == Process.myPid()) {
4581                    Log.w(TAG, "crashApplication: trying to crash self!");
4582                    return;
4583                }
4584                long ident = Binder.clearCallingIdentity();
4585                try {
4586                    proc.thread.scheduleCrash(message);
4587                } catch (RemoteException e) {
4588                }
4589                Binder.restoreCallingIdentity(ident);
4590            }
4591        }
4592    }
4593
4594    @Override
4595    public final void finishSubActivity(IBinder token, String resultWho,
4596            int requestCode) {
4597        synchronized(this) {
4598            final long origId = Binder.clearCallingIdentity();
4599            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4600            if (r != null) {
4601                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4602            }
4603            Binder.restoreCallingIdentity(origId);
4604        }
4605    }
4606
4607    @Override
4608    public boolean finishActivityAffinity(IBinder token) {
4609        synchronized(this) {
4610            final long origId = Binder.clearCallingIdentity();
4611            try {
4612                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4613
4614                ActivityRecord rootR = r.task.getRootActivity();
4615                // Do not allow task to finish in Lock Task mode.
4616                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4617                    if (rootR == r) {
4618                        mStackSupervisor.showLockTaskToast();
4619                        return false;
4620                    }
4621                }
4622                boolean res = false;
4623                if (r != null) {
4624                    res = r.task.stack.finishActivityAffinityLocked(r);
4625                }
4626                return res;
4627            } finally {
4628                Binder.restoreCallingIdentity(origId);
4629            }
4630        }
4631    }
4632
4633    @Override
4634    public void finishVoiceTask(IVoiceInteractionSession session) {
4635        synchronized(this) {
4636            final long origId = Binder.clearCallingIdentity();
4637            try {
4638                mStackSupervisor.finishVoiceTask(session);
4639            } finally {
4640                Binder.restoreCallingIdentity(origId);
4641            }
4642        }
4643
4644    }
4645
4646    @Override
4647    public boolean releaseActivityInstance(IBinder token) {
4648        synchronized(this) {
4649            final long origId = Binder.clearCallingIdentity();
4650            try {
4651                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4652                if (r.task == null || r.task.stack == null) {
4653                    return false;
4654                }
4655                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4656            } finally {
4657                Binder.restoreCallingIdentity(origId);
4658            }
4659        }
4660    }
4661
4662    @Override
4663    public void releaseSomeActivities(IApplicationThread appInt) {
4664        synchronized(this) {
4665            final long origId = Binder.clearCallingIdentity();
4666            try {
4667                ProcessRecord app = getRecordForAppLocked(appInt);
4668                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4669            } finally {
4670                Binder.restoreCallingIdentity(origId);
4671            }
4672        }
4673    }
4674
4675    @Override
4676    public boolean willActivityBeVisible(IBinder token) {
4677        synchronized(this) {
4678            ActivityStack stack = ActivityRecord.getStackLocked(token);
4679            if (stack != null) {
4680                return stack.willActivityBeVisibleLocked(token);
4681            }
4682            return false;
4683        }
4684    }
4685
4686    @Override
4687    public void overridePendingTransition(IBinder token, String packageName,
4688            int enterAnim, int exitAnim) {
4689        synchronized(this) {
4690            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4691            if (self == null) {
4692                return;
4693            }
4694
4695            final long origId = Binder.clearCallingIdentity();
4696
4697            if (self.state == ActivityState.RESUMED
4698                    || self.state == ActivityState.PAUSING) {
4699                mWindowManager.overridePendingAppTransition(packageName,
4700                        enterAnim, exitAnim, null);
4701            }
4702
4703            Binder.restoreCallingIdentity(origId);
4704        }
4705    }
4706
4707    /**
4708     * Main function for removing an existing process from the activity manager
4709     * as a result of that process going away.  Clears out all connections
4710     * to the process.
4711     */
4712    private final void handleAppDiedLocked(ProcessRecord app,
4713            boolean restarting, boolean allowRestart) {
4714        int pid = app.pid;
4715        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4716        if (!kept && !restarting) {
4717            removeLruProcessLocked(app);
4718            if (pid > 0) {
4719                ProcessList.remove(pid);
4720            }
4721        }
4722
4723        if (mProfileProc == app) {
4724            clearProfilerLocked();
4725        }
4726
4727        // Remove this application's activities from active lists.
4728        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4729
4730        app.activities.clear();
4731
4732        if (app.instrumentationClass != null) {
4733            Slog.w(TAG, "Crash of app " + app.processName
4734                  + " running instrumentation " + app.instrumentationClass);
4735            Bundle info = new Bundle();
4736            info.putString("shortMsg", "Process crashed.");
4737            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4738        }
4739
4740        if (!restarting) {
4741            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4742                // If there was nothing to resume, and we are not already
4743                // restarting this process, but there is a visible activity that
4744                // is hosted by the process...  then make sure all visible
4745                // activities are running, taking care of restarting this
4746                // process.
4747                if (hasVisibleActivities) {
4748                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4749                }
4750            }
4751        }
4752    }
4753
4754    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4755        IBinder threadBinder = thread.asBinder();
4756        // Find the application record.
4757        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4758            ProcessRecord rec = mLruProcesses.get(i);
4759            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4760                return i;
4761            }
4762        }
4763        return -1;
4764    }
4765
4766    final ProcessRecord getRecordForAppLocked(
4767            IApplicationThread thread) {
4768        if (thread == null) {
4769            return null;
4770        }
4771
4772        int appIndex = getLRURecordIndexForAppLocked(thread);
4773        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4774    }
4775
4776    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4777        // If there are no longer any background processes running,
4778        // and the app that died was not running instrumentation,
4779        // then tell everyone we are now low on memory.
4780        boolean haveBg = false;
4781        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4782            ProcessRecord rec = mLruProcesses.get(i);
4783            if (rec.thread != null
4784                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4785                haveBg = true;
4786                break;
4787            }
4788        }
4789
4790        if (!haveBg) {
4791            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4792            if (doReport) {
4793                long now = SystemClock.uptimeMillis();
4794                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4795                    doReport = false;
4796                } else {
4797                    mLastMemUsageReportTime = now;
4798                }
4799            }
4800            final ArrayList<ProcessMemInfo> memInfos
4801                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4802            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4803            long now = SystemClock.uptimeMillis();
4804            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4805                ProcessRecord rec = mLruProcesses.get(i);
4806                if (rec == dyingProc || rec.thread == null) {
4807                    continue;
4808                }
4809                if (doReport) {
4810                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4811                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4812                }
4813                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4814                    // The low memory report is overriding any current
4815                    // state for a GC request.  Make sure to do
4816                    // heavy/important/visible/foreground processes first.
4817                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4818                        rec.lastRequestedGc = 0;
4819                    } else {
4820                        rec.lastRequestedGc = rec.lastLowMemory;
4821                    }
4822                    rec.reportLowMemory = true;
4823                    rec.lastLowMemory = now;
4824                    mProcessesToGc.remove(rec);
4825                    addProcessToGcListLocked(rec);
4826                }
4827            }
4828            if (doReport) {
4829                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4830                mHandler.sendMessage(msg);
4831            }
4832            scheduleAppGcsLocked();
4833        }
4834    }
4835
4836    final void appDiedLocked(ProcessRecord app) {
4837       appDiedLocked(app, app.pid, app.thread);
4838    }
4839
4840    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4841        // First check if this ProcessRecord is actually active for the pid.
4842        synchronized (mPidsSelfLocked) {
4843            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4844            if (curProc != app) {
4845                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4846                return;
4847            }
4848        }
4849
4850        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4851        synchronized (stats) {
4852            stats.noteProcessDiedLocked(app.info.uid, pid);
4853        }
4854
4855        Process.killProcessQuiet(pid);
4856        Process.killProcessGroup(app.info.uid, pid);
4857        app.killed = true;
4858
4859        // Clean up already done if the process has been re-started.
4860        if (app.pid == pid && app.thread != null &&
4861                app.thread.asBinder() == thread.asBinder()) {
4862            boolean doLowMem = app.instrumentationClass == null;
4863            boolean doOomAdj = doLowMem;
4864            if (!app.killedByAm) {
4865                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4866                        + ") has died");
4867                mAllowLowerMemLevel = true;
4868            } else {
4869                // Note that we always want to do oom adj to update our state with the
4870                // new number of procs.
4871                mAllowLowerMemLevel = false;
4872                doLowMem = false;
4873            }
4874            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4875            if (DEBUG_CLEANUP) Slog.v(
4876                TAG, "Dying app: " + app + ", pid: " + pid
4877                + ", thread: " + thread.asBinder());
4878            handleAppDiedLocked(app, false, true);
4879
4880            if (doOomAdj) {
4881                updateOomAdjLocked();
4882            }
4883            if (doLowMem) {
4884                doLowMemReportIfNeededLocked(app);
4885            }
4886        } else if (app.pid != pid) {
4887            // A new process has already been started.
4888            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4889                    + ") has died and restarted (pid " + app.pid + ").");
4890            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4891        } else if (DEBUG_PROCESSES) {
4892            Slog.d(TAG, "Received spurious death notification for thread "
4893                    + thread.asBinder());
4894        }
4895    }
4896
4897    /**
4898     * If a stack trace dump file is configured, dump process stack traces.
4899     * @param clearTraces causes the dump file to be erased prior to the new
4900     *    traces being written, if true; when false, the new traces will be
4901     *    appended to any existing file content.
4902     * @param firstPids of dalvik VM processes to dump stack traces for first
4903     * @param lastPids of dalvik VM processes to dump stack traces for last
4904     * @param nativeProcs optional list of native process names to dump stack crawls
4905     * @return file containing stack traces, or null if no dump file is configured
4906     */
4907    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4908            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4909        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4910        if (tracesPath == null || tracesPath.length() == 0) {
4911            return null;
4912        }
4913
4914        File tracesFile = new File(tracesPath);
4915        try {
4916            File tracesDir = tracesFile.getParentFile();
4917            if (!tracesDir.exists()) {
4918                tracesDir.mkdirs();
4919                if (!SELinux.restorecon(tracesDir)) {
4920                    return null;
4921                }
4922            }
4923            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4924
4925            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4926            tracesFile.createNewFile();
4927            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4928        } catch (IOException e) {
4929            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4930            return null;
4931        }
4932
4933        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4934        return tracesFile;
4935    }
4936
4937    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4938            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4939        // Use a FileObserver to detect when traces finish writing.
4940        // The order of traces is considered important to maintain for legibility.
4941        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4942            @Override
4943            public synchronized void onEvent(int event, String path) { notify(); }
4944        };
4945
4946        try {
4947            observer.startWatching();
4948
4949            // First collect all of the stacks of the most important pids.
4950            if (firstPids != null) {
4951                try {
4952                    int num = firstPids.size();
4953                    for (int i = 0; i < num; i++) {
4954                        synchronized (observer) {
4955                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4956                            observer.wait(200);  // Wait for write-close, give up after 200msec
4957                        }
4958                    }
4959                } catch (InterruptedException e) {
4960                    Slog.wtf(TAG, e);
4961                }
4962            }
4963
4964            // Next collect the stacks of the native pids
4965            if (nativeProcs != null) {
4966                int[] pids = Process.getPidsForCommands(nativeProcs);
4967                if (pids != null) {
4968                    for (int pid : pids) {
4969                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4970                    }
4971                }
4972            }
4973
4974            // Lastly, measure CPU usage.
4975            if (processCpuTracker != null) {
4976                processCpuTracker.init();
4977                System.gc();
4978                processCpuTracker.update();
4979                try {
4980                    synchronized (processCpuTracker) {
4981                        processCpuTracker.wait(500); // measure over 1/2 second.
4982                    }
4983                } catch (InterruptedException e) {
4984                }
4985                processCpuTracker.update();
4986
4987                // We'll take the stack crawls of just the top apps using CPU.
4988                final int N = processCpuTracker.countWorkingStats();
4989                int numProcs = 0;
4990                for (int i=0; i<N && numProcs<5; i++) {
4991                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4992                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4993                        numProcs++;
4994                        try {
4995                            synchronized (observer) {
4996                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4997                                observer.wait(200);  // Wait for write-close, give up after 200msec
4998                            }
4999                        } catch (InterruptedException e) {
5000                            Slog.wtf(TAG, e);
5001                        }
5002
5003                    }
5004                }
5005            }
5006        } finally {
5007            observer.stopWatching();
5008        }
5009    }
5010
5011    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5012        if (true || IS_USER_BUILD) {
5013            return;
5014        }
5015        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5016        if (tracesPath == null || tracesPath.length() == 0) {
5017            return;
5018        }
5019
5020        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5021        StrictMode.allowThreadDiskWrites();
5022        try {
5023            final File tracesFile = new File(tracesPath);
5024            final File tracesDir = tracesFile.getParentFile();
5025            final File tracesTmp = new File(tracesDir, "__tmp__");
5026            try {
5027                if (!tracesDir.exists()) {
5028                    tracesDir.mkdirs();
5029                    if (!SELinux.restorecon(tracesDir.getPath())) {
5030                        return;
5031                    }
5032                }
5033                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5034
5035                if (tracesFile.exists()) {
5036                    tracesTmp.delete();
5037                    tracesFile.renameTo(tracesTmp);
5038                }
5039                StringBuilder sb = new StringBuilder();
5040                Time tobj = new Time();
5041                tobj.set(System.currentTimeMillis());
5042                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5043                sb.append(": ");
5044                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5045                sb.append(" since ");
5046                sb.append(msg);
5047                FileOutputStream fos = new FileOutputStream(tracesFile);
5048                fos.write(sb.toString().getBytes());
5049                if (app == null) {
5050                    fos.write("\n*** No application process!".getBytes());
5051                }
5052                fos.close();
5053                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5054            } catch (IOException e) {
5055                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5056                return;
5057            }
5058
5059            if (app != null) {
5060                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5061                firstPids.add(app.pid);
5062                dumpStackTraces(tracesPath, firstPids, null, null, null);
5063            }
5064
5065            File lastTracesFile = null;
5066            File curTracesFile = null;
5067            for (int i=9; i>=0; i--) {
5068                String name = String.format(Locale.US, "slow%02d.txt", i);
5069                curTracesFile = new File(tracesDir, name);
5070                if (curTracesFile.exists()) {
5071                    if (lastTracesFile != null) {
5072                        curTracesFile.renameTo(lastTracesFile);
5073                    } else {
5074                        curTracesFile.delete();
5075                    }
5076                }
5077                lastTracesFile = curTracesFile;
5078            }
5079            tracesFile.renameTo(curTracesFile);
5080            if (tracesTmp.exists()) {
5081                tracesTmp.renameTo(tracesFile);
5082            }
5083        } finally {
5084            StrictMode.setThreadPolicy(oldPolicy);
5085        }
5086    }
5087
5088    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5089            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5090        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5091        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5092
5093        if (mController != null) {
5094            try {
5095                // 0 == continue, -1 = kill process immediately
5096                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5097                if (res < 0 && app.pid != MY_PID) {
5098                    app.kill("anr", true);
5099                }
5100            } catch (RemoteException e) {
5101                mController = null;
5102                Watchdog.getInstance().setActivityController(null);
5103            }
5104        }
5105
5106        long anrTime = SystemClock.uptimeMillis();
5107        if (MONITOR_CPU_USAGE) {
5108            updateCpuStatsNow();
5109        }
5110
5111        synchronized (this) {
5112            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5113            if (mShuttingDown) {
5114                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5115                return;
5116            } else if (app.notResponding) {
5117                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5118                return;
5119            } else if (app.crashing) {
5120                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5121                return;
5122            }
5123
5124            // In case we come through here for the same app before completing
5125            // this one, mark as anring now so we will bail out.
5126            app.notResponding = true;
5127
5128            // Log the ANR to the event log.
5129            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5130                    app.processName, app.info.flags, annotation);
5131
5132            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5133            firstPids.add(app.pid);
5134
5135            int parentPid = app.pid;
5136            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5137            if (parentPid != app.pid) firstPids.add(parentPid);
5138
5139            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5140
5141            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5142                ProcessRecord r = mLruProcesses.get(i);
5143                if (r != null && r.thread != null) {
5144                    int pid = r.pid;
5145                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5146                        if (r.persistent) {
5147                            firstPids.add(pid);
5148                        } else {
5149                            lastPids.put(pid, Boolean.TRUE);
5150                        }
5151                    }
5152                }
5153            }
5154        }
5155
5156        // Log the ANR to the main log.
5157        StringBuilder info = new StringBuilder();
5158        info.setLength(0);
5159        info.append("ANR in ").append(app.processName);
5160        if (activity != null && activity.shortComponentName != null) {
5161            info.append(" (").append(activity.shortComponentName).append(")");
5162        }
5163        info.append("\n");
5164        info.append("PID: ").append(app.pid).append("\n");
5165        if (annotation != null) {
5166            info.append("Reason: ").append(annotation).append("\n");
5167        }
5168        if (parent != null && parent != activity) {
5169            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5170        }
5171
5172        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5173
5174        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5175                NATIVE_STACKS_OF_INTEREST);
5176
5177        String cpuInfo = null;
5178        if (MONITOR_CPU_USAGE) {
5179            updateCpuStatsNow();
5180            synchronized (mProcessCpuTracker) {
5181                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5182            }
5183            info.append(processCpuTracker.printCurrentLoad());
5184            info.append(cpuInfo);
5185        }
5186
5187        info.append(processCpuTracker.printCurrentState(anrTime));
5188
5189        Slog.e(TAG, info.toString());
5190        if (tracesFile == null) {
5191            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5192            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5193        }
5194
5195        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5196                cpuInfo, tracesFile, null);
5197
5198        if (mController != null) {
5199            try {
5200                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5201                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5202                if (res != 0) {
5203                    if (res < 0 && app.pid != MY_PID) {
5204                        app.kill("anr", true);
5205                    } else {
5206                        synchronized (this) {
5207                            mServices.scheduleServiceTimeoutLocked(app);
5208                        }
5209                    }
5210                    return;
5211                }
5212            } catch (RemoteException e) {
5213                mController = null;
5214                Watchdog.getInstance().setActivityController(null);
5215            }
5216        }
5217
5218        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5219        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5220                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5221
5222        synchronized (this) {
5223            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5224                app.kill("bg anr", true);
5225                return;
5226            }
5227
5228            // Set the app's notResponding state, and look up the errorReportReceiver
5229            makeAppNotRespondingLocked(app,
5230                    activity != null ? activity.shortComponentName : null,
5231                    annotation != null ? "ANR " + annotation : "ANR",
5232                    info.toString());
5233
5234            // Bring up the infamous App Not Responding dialog
5235            Message msg = Message.obtain();
5236            HashMap<String, Object> map = new HashMap<String, Object>();
5237            msg.what = SHOW_NOT_RESPONDING_MSG;
5238            msg.obj = map;
5239            msg.arg1 = aboveSystem ? 1 : 0;
5240            map.put("app", app);
5241            if (activity != null) {
5242                map.put("activity", activity);
5243            }
5244
5245            mHandler.sendMessage(msg);
5246        }
5247    }
5248
5249    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5250        if (!mLaunchWarningShown) {
5251            mLaunchWarningShown = true;
5252            mHandler.post(new Runnable() {
5253                @Override
5254                public void run() {
5255                    synchronized (ActivityManagerService.this) {
5256                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5257                        d.show();
5258                        mHandler.postDelayed(new Runnable() {
5259                            @Override
5260                            public void run() {
5261                                synchronized (ActivityManagerService.this) {
5262                                    d.dismiss();
5263                                    mLaunchWarningShown = false;
5264                                }
5265                            }
5266                        }, 4000);
5267                    }
5268                }
5269            });
5270        }
5271    }
5272
5273    @Override
5274    public boolean clearApplicationUserData(final String packageName,
5275            final IPackageDataObserver observer, int userId) {
5276        enforceNotIsolatedCaller("clearApplicationUserData");
5277        int uid = Binder.getCallingUid();
5278        int pid = Binder.getCallingPid();
5279        userId = handleIncomingUser(pid, uid,
5280                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5281        long callingId = Binder.clearCallingIdentity();
5282        try {
5283            IPackageManager pm = AppGlobals.getPackageManager();
5284            int pkgUid = -1;
5285            synchronized(this) {
5286                try {
5287                    pkgUid = pm.getPackageUid(packageName, userId);
5288                } catch (RemoteException e) {
5289                }
5290                if (pkgUid == -1) {
5291                    Slog.w(TAG, "Invalid packageName: " + packageName);
5292                    if (observer != null) {
5293                        try {
5294                            observer.onRemoveCompleted(packageName, false);
5295                        } catch (RemoteException e) {
5296                            Slog.i(TAG, "Observer no longer exists.");
5297                        }
5298                    }
5299                    return false;
5300                }
5301                if (uid == pkgUid || checkComponentPermission(
5302                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5303                        pid, uid, -1, true)
5304                        == PackageManager.PERMISSION_GRANTED) {
5305                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5306                } else {
5307                    throw new SecurityException("PID " + pid + " does not have permission "
5308                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5309                                    + " of package " + packageName);
5310                }
5311
5312                // Remove all tasks match the cleared application package and user
5313                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5314                    final TaskRecord tr = mRecentTasks.get(i);
5315                    final String taskPackageName =
5316                            tr.getBaseIntent().getComponent().getPackageName();
5317                    if (tr.userId != userId) continue;
5318                    if (!taskPackageName.equals(packageName)) continue;
5319                    removeTaskByIdLocked(tr.taskId, 0);
5320                }
5321            }
5322
5323            try {
5324                // Clear application user data
5325                pm.clearApplicationUserData(packageName, observer, userId);
5326
5327                synchronized(this) {
5328                    // Remove all permissions granted from/to this package
5329                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5330                }
5331
5332                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5333                        Uri.fromParts("package", packageName, null));
5334                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5335                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5336                        null, null, 0, null, null, null, false, false, userId);
5337            } catch (RemoteException e) {
5338            }
5339        } finally {
5340            Binder.restoreCallingIdentity(callingId);
5341        }
5342        return true;
5343    }
5344
5345    @Override
5346    public void killBackgroundProcesses(final String packageName, int userId) {
5347        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5348                != PackageManager.PERMISSION_GRANTED &&
5349                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5350                        != PackageManager.PERMISSION_GRANTED) {
5351            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5352                    + Binder.getCallingPid()
5353                    + ", uid=" + Binder.getCallingUid()
5354                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5355            Slog.w(TAG, msg);
5356            throw new SecurityException(msg);
5357        }
5358
5359        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5360                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5361        long callingId = Binder.clearCallingIdentity();
5362        try {
5363            IPackageManager pm = AppGlobals.getPackageManager();
5364            synchronized(this) {
5365                int appId = -1;
5366                try {
5367                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5368                } catch (RemoteException e) {
5369                }
5370                if (appId == -1) {
5371                    Slog.w(TAG, "Invalid packageName: " + packageName);
5372                    return;
5373                }
5374                killPackageProcessesLocked(packageName, appId, userId,
5375                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5376            }
5377        } finally {
5378            Binder.restoreCallingIdentity(callingId);
5379        }
5380    }
5381
5382    @Override
5383    public void killAllBackgroundProcesses() {
5384        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5385                != PackageManager.PERMISSION_GRANTED) {
5386            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5387                    + Binder.getCallingPid()
5388                    + ", uid=" + Binder.getCallingUid()
5389                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5390            Slog.w(TAG, msg);
5391            throw new SecurityException(msg);
5392        }
5393
5394        long callingId = Binder.clearCallingIdentity();
5395        try {
5396            synchronized(this) {
5397                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5398                final int NP = mProcessNames.getMap().size();
5399                for (int ip=0; ip<NP; ip++) {
5400                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5401                    final int NA = apps.size();
5402                    for (int ia=0; ia<NA; ia++) {
5403                        ProcessRecord app = apps.valueAt(ia);
5404                        if (app.persistent) {
5405                            // we don't kill persistent processes
5406                            continue;
5407                        }
5408                        if (app.removed) {
5409                            procs.add(app);
5410                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5411                            app.removed = true;
5412                            procs.add(app);
5413                        }
5414                    }
5415                }
5416
5417                int N = procs.size();
5418                for (int i=0; i<N; i++) {
5419                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5420                }
5421                mAllowLowerMemLevel = true;
5422                updateOomAdjLocked();
5423                doLowMemReportIfNeededLocked(null);
5424            }
5425        } finally {
5426            Binder.restoreCallingIdentity(callingId);
5427        }
5428    }
5429
5430    @Override
5431    public void forceStopPackage(final String packageName, int userId) {
5432        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5433                != PackageManager.PERMISSION_GRANTED) {
5434            String msg = "Permission Denial: forceStopPackage() from pid="
5435                    + Binder.getCallingPid()
5436                    + ", uid=" + Binder.getCallingUid()
5437                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5438            Slog.w(TAG, msg);
5439            throw new SecurityException(msg);
5440        }
5441        final int callingPid = Binder.getCallingPid();
5442        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5443                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5444        long callingId = Binder.clearCallingIdentity();
5445        try {
5446            IPackageManager pm = AppGlobals.getPackageManager();
5447            synchronized(this) {
5448                int[] users = userId == UserHandle.USER_ALL
5449                        ? getUsersLocked() : new int[] { userId };
5450                for (int user : users) {
5451                    int pkgUid = -1;
5452                    try {
5453                        pkgUid = pm.getPackageUid(packageName, user);
5454                    } catch (RemoteException e) {
5455                    }
5456                    if (pkgUid == -1) {
5457                        Slog.w(TAG, "Invalid packageName: " + packageName);
5458                        continue;
5459                    }
5460                    try {
5461                        pm.setPackageStoppedState(packageName, true, user);
5462                    } catch (RemoteException e) {
5463                    } catch (IllegalArgumentException e) {
5464                        Slog.w(TAG, "Failed trying to unstop package "
5465                                + packageName + ": " + e);
5466                    }
5467                    if (isUserRunningLocked(user, false)) {
5468                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5469                    }
5470                }
5471            }
5472        } finally {
5473            Binder.restoreCallingIdentity(callingId);
5474        }
5475    }
5476
5477    @Override
5478    public void addPackageDependency(String packageName) {
5479        synchronized (this) {
5480            int callingPid = Binder.getCallingPid();
5481            if (callingPid == Process.myPid()) {
5482                //  Yeah, um, no.
5483                Slog.w(TAG, "Can't addPackageDependency on system process");
5484                return;
5485            }
5486            ProcessRecord proc;
5487            synchronized (mPidsSelfLocked) {
5488                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5489            }
5490            if (proc != null) {
5491                if (proc.pkgDeps == null) {
5492                    proc.pkgDeps = new ArraySet<String>(1);
5493                }
5494                proc.pkgDeps.add(packageName);
5495            }
5496        }
5497    }
5498
5499    /*
5500     * The pkg name and app id have to be specified.
5501     */
5502    @Override
5503    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5504        if (pkg == null) {
5505            return;
5506        }
5507        // Make sure the uid is valid.
5508        if (appid < 0) {
5509            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5510            return;
5511        }
5512        int callerUid = Binder.getCallingUid();
5513        // Only the system server can kill an application
5514        if (callerUid == Process.SYSTEM_UID) {
5515            // Post an aysnc message to kill the application
5516            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5517            msg.arg1 = appid;
5518            msg.arg2 = 0;
5519            Bundle bundle = new Bundle();
5520            bundle.putString("pkg", pkg);
5521            bundle.putString("reason", reason);
5522            msg.obj = bundle;
5523            mHandler.sendMessage(msg);
5524        } else {
5525            throw new SecurityException(callerUid + " cannot kill pkg: " +
5526                    pkg);
5527        }
5528    }
5529
5530    @Override
5531    public void closeSystemDialogs(String reason) {
5532        enforceNotIsolatedCaller("closeSystemDialogs");
5533
5534        final int pid = Binder.getCallingPid();
5535        final int uid = Binder.getCallingUid();
5536        final long origId = Binder.clearCallingIdentity();
5537        try {
5538            synchronized (this) {
5539                // Only allow this from foreground processes, so that background
5540                // applications can't abuse it to prevent system UI from being shown.
5541                if (uid >= Process.FIRST_APPLICATION_UID) {
5542                    ProcessRecord proc;
5543                    synchronized (mPidsSelfLocked) {
5544                        proc = mPidsSelfLocked.get(pid);
5545                    }
5546                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5547                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5548                                + " from background process " + proc);
5549                        return;
5550                    }
5551                }
5552                closeSystemDialogsLocked(reason);
5553            }
5554        } finally {
5555            Binder.restoreCallingIdentity(origId);
5556        }
5557    }
5558
5559    void closeSystemDialogsLocked(String reason) {
5560        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5561        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5562                | Intent.FLAG_RECEIVER_FOREGROUND);
5563        if (reason != null) {
5564            intent.putExtra("reason", reason);
5565        }
5566        mWindowManager.closeSystemDialogs(reason);
5567
5568        mStackSupervisor.closeSystemDialogsLocked();
5569
5570        broadcastIntentLocked(null, null, intent, null,
5571                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5572                Process.SYSTEM_UID, UserHandle.USER_ALL);
5573    }
5574
5575    @Override
5576    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5577        enforceNotIsolatedCaller("getProcessMemoryInfo");
5578        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5579        for (int i=pids.length-1; i>=0; i--) {
5580            ProcessRecord proc;
5581            int oomAdj;
5582            synchronized (this) {
5583                synchronized (mPidsSelfLocked) {
5584                    proc = mPidsSelfLocked.get(pids[i]);
5585                    oomAdj = proc != null ? proc.setAdj : 0;
5586                }
5587            }
5588            infos[i] = new Debug.MemoryInfo();
5589            Debug.getMemoryInfo(pids[i], infos[i]);
5590            if (proc != null) {
5591                synchronized (this) {
5592                    if (proc.thread != null && proc.setAdj == oomAdj) {
5593                        // Record this for posterity if the process has been stable.
5594                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5595                                infos[i].getTotalUss(), false, proc.pkgList);
5596                    }
5597                }
5598            }
5599        }
5600        return infos;
5601    }
5602
5603    @Override
5604    public long[] getProcessPss(int[] pids) {
5605        enforceNotIsolatedCaller("getProcessPss");
5606        long[] pss = new long[pids.length];
5607        for (int i=pids.length-1; i>=0; i--) {
5608            ProcessRecord proc;
5609            int oomAdj;
5610            synchronized (this) {
5611                synchronized (mPidsSelfLocked) {
5612                    proc = mPidsSelfLocked.get(pids[i]);
5613                    oomAdj = proc != null ? proc.setAdj : 0;
5614                }
5615            }
5616            long[] tmpUss = new long[1];
5617            pss[i] = Debug.getPss(pids[i], tmpUss);
5618            if (proc != null) {
5619                synchronized (this) {
5620                    if (proc.thread != null && proc.setAdj == oomAdj) {
5621                        // Record this for posterity if the process has been stable.
5622                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5623                    }
5624                }
5625            }
5626        }
5627        return pss;
5628    }
5629
5630    @Override
5631    public void killApplicationProcess(String processName, int uid) {
5632        if (processName == null) {
5633            return;
5634        }
5635
5636        int callerUid = Binder.getCallingUid();
5637        // Only the system server can kill an application
5638        if (callerUid == Process.SYSTEM_UID) {
5639            synchronized (this) {
5640                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5641                if (app != null && app.thread != null) {
5642                    try {
5643                        app.thread.scheduleSuicide();
5644                    } catch (RemoteException e) {
5645                        // If the other end already died, then our work here is done.
5646                    }
5647                } else {
5648                    Slog.w(TAG, "Process/uid not found attempting kill of "
5649                            + processName + " / " + uid);
5650                }
5651            }
5652        } else {
5653            throw new SecurityException(callerUid + " cannot kill app process: " +
5654                    processName);
5655        }
5656    }
5657
5658    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5659        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5660                false, true, false, false, UserHandle.getUserId(uid), reason);
5661        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5662                Uri.fromParts("package", packageName, null));
5663        if (!mProcessesReady) {
5664            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5665                    | Intent.FLAG_RECEIVER_FOREGROUND);
5666        }
5667        intent.putExtra(Intent.EXTRA_UID, uid);
5668        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5669        broadcastIntentLocked(null, null, intent,
5670                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5671                false, false,
5672                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5673    }
5674
5675    private void forceStopUserLocked(int userId, String reason) {
5676        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5677        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5678        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5679                | Intent.FLAG_RECEIVER_FOREGROUND);
5680        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5681        broadcastIntentLocked(null, null, intent,
5682                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5683                false, false,
5684                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5685    }
5686
5687    private final boolean killPackageProcessesLocked(String packageName, int appId,
5688            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5689            boolean doit, boolean evenPersistent, String reason) {
5690        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5691
5692        // Remove all processes this package may have touched: all with the
5693        // same UID (except for the system or root user), and all whose name
5694        // matches the package name.
5695        final int NP = mProcessNames.getMap().size();
5696        for (int ip=0; ip<NP; ip++) {
5697            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5698            final int NA = apps.size();
5699            for (int ia=0; ia<NA; ia++) {
5700                ProcessRecord app = apps.valueAt(ia);
5701                if (app.persistent && !evenPersistent) {
5702                    // we don't kill persistent processes
5703                    continue;
5704                }
5705                if (app.removed) {
5706                    if (doit) {
5707                        procs.add(app);
5708                    }
5709                    continue;
5710                }
5711
5712                // Skip process if it doesn't meet our oom adj requirement.
5713                if (app.setAdj < minOomAdj) {
5714                    continue;
5715                }
5716
5717                // If no package is specified, we call all processes under the
5718                // give user id.
5719                if (packageName == null) {
5720                    if (app.userId != userId) {
5721                        continue;
5722                    }
5723                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5724                        continue;
5725                    }
5726                // Package has been specified, we want to hit all processes
5727                // that match it.  We need to qualify this by the processes
5728                // that are running under the specified app and user ID.
5729                } else {
5730                    final boolean isDep = app.pkgDeps != null
5731                            && app.pkgDeps.contains(packageName);
5732                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5733                        continue;
5734                    }
5735                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5736                        continue;
5737                    }
5738                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5739                        continue;
5740                    }
5741                }
5742
5743                // Process has passed all conditions, kill it!
5744                if (!doit) {
5745                    return true;
5746                }
5747                app.removed = true;
5748                procs.add(app);
5749            }
5750        }
5751
5752        int N = procs.size();
5753        for (int i=0; i<N; i++) {
5754            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5755        }
5756        updateOomAdjLocked();
5757        return N > 0;
5758    }
5759
5760    private final boolean forceStopPackageLocked(String name, int appId,
5761            boolean callerWillRestart, boolean purgeCache, boolean doit,
5762            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5763        int i;
5764        int N;
5765
5766        if (userId == UserHandle.USER_ALL && name == null) {
5767            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5768        }
5769
5770        if (appId < 0 && name != null) {
5771            try {
5772                appId = UserHandle.getAppId(
5773                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5774            } catch (RemoteException e) {
5775            }
5776        }
5777
5778        if (doit) {
5779            if (name != null) {
5780                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5781                        + " user=" + userId + ": " + reason);
5782            } else {
5783                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5784            }
5785
5786            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5787            for (int ip=pmap.size()-1; ip>=0; ip--) {
5788                SparseArray<Long> ba = pmap.valueAt(ip);
5789                for (i=ba.size()-1; i>=0; i--) {
5790                    boolean remove = false;
5791                    final int entUid = ba.keyAt(i);
5792                    if (name != null) {
5793                        if (userId == UserHandle.USER_ALL) {
5794                            if (UserHandle.getAppId(entUid) == appId) {
5795                                remove = true;
5796                            }
5797                        } else {
5798                            if (entUid == UserHandle.getUid(userId, appId)) {
5799                                remove = true;
5800                            }
5801                        }
5802                    } else if (UserHandle.getUserId(entUid) == userId) {
5803                        remove = true;
5804                    }
5805                    if (remove) {
5806                        ba.removeAt(i);
5807                    }
5808                }
5809                if (ba.size() == 0) {
5810                    pmap.removeAt(ip);
5811                }
5812            }
5813        }
5814
5815        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5816                -100, callerWillRestart, true, doit, evenPersistent,
5817                name == null ? ("stop user " + userId) : ("stop " + name));
5818
5819        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5820            if (!doit) {
5821                return true;
5822            }
5823            didSomething = true;
5824        }
5825
5826        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5827            if (!doit) {
5828                return true;
5829            }
5830            didSomething = true;
5831        }
5832
5833        if (name == null) {
5834            // Remove all sticky broadcasts from this user.
5835            mStickyBroadcasts.remove(userId);
5836        }
5837
5838        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5839        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5840                userId, providers)) {
5841            if (!doit) {
5842                return true;
5843            }
5844            didSomething = true;
5845        }
5846        N = providers.size();
5847        for (i=0; i<N; i++) {
5848            removeDyingProviderLocked(null, providers.get(i), true);
5849        }
5850
5851        // Remove transient permissions granted from/to this package/user
5852        removeUriPermissionsForPackageLocked(name, userId, false);
5853
5854        if (name == null || uninstalling) {
5855            // Remove pending intents.  For now we only do this when force
5856            // stopping users, because we have some problems when doing this
5857            // for packages -- app widgets are not currently cleaned up for
5858            // such packages, so they can be left with bad pending intents.
5859            if (mIntentSenderRecords.size() > 0) {
5860                Iterator<WeakReference<PendingIntentRecord>> it
5861                        = mIntentSenderRecords.values().iterator();
5862                while (it.hasNext()) {
5863                    WeakReference<PendingIntentRecord> wpir = it.next();
5864                    if (wpir == null) {
5865                        it.remove();
5866                        continue;
5867                    }
5868                    PendingIntentRecord pir = wpir.get();
5869                    if (pir == null) {
5870                        it.remove();
5871                        continue;
5872                    }
5873                    if (name == null) {
5874                        // Stopping user, remove all objects for the user.
5875                        if (pir.key.userId != userId) {
5876                            // Not the same user, skip it.
5877                            continue;
5878                        }
5879                    } else {
5880                        if (UserHandle.getAppId(pir.uid) != appId) {
5881                            // Different app id, skip it.
5882                            continue;
5883                        }
5884                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5885                            // Different user, skip it.
5886                            continue;
5887                        }
5888                        if (!pir.key.packageName.equals(name)) {
5889                            // Different package, skip it.
5890                            continue;
5891                        }
5892                    }
5893                    if (!doit) {
5894                        return true;
5895                    }
5896                    didSomething = true;
5897                    it.remove();
5898                    pir.canceled = true;
5899                    if (pir.key.activity != null) {
5900                        pir.key.activity.pendingResults.remove(pir.ref);
5901                    }
5902                }
5903            }
5904        }
5905
5906        if (doit) {
5907            if (purgeCache && name != null) {
5908                AttributeCache ac = AttributeCache.instance();
5909                if (ac != null) {
5910                    ac.removePackage(name);
5911                }
5912            }
5913            if (mBooted) {
5914                mStackSupervisor.resumeTopActivitiesLocked();
5915                mStackSupervisor.scheduleIdleLocked();
5916            }
5917        }
5918
5919        return didSomething;
5920    }
5921
5922    private final boolean removeProcessLocked(ProcessRecord app,
5923            boolean callerWillRestart, boolean allowRestart, String reason) {
5924        final String name = app.processName;
5925        final int uid = app.uid;
5926        if (DEBUG_PROCESSES) Slog.d(
5927            TAG, "Force removing proc " + app.toShortString() + " (" + name
5928            + "/" + uid + ")");
5929
5930        mProcessNames.remove(name, uid);
5931        mIsolatedProcesses.remove(app.uid);
5932        if (mHeavyWeightProcess == app) {
5933            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5934                    mHeavyWeightProcess.userId, 0));
5935            mHeavyWeightProcess = null;
5936        }
5937        boolean needRestart = false;
5938        if (app.pid > 0 && app.pid != MY_PID) {
5939            int pid = app.pid;
5940            synchronized (mPidsSelfLocked) {
5941                mPidsSelfLocked.remove(pid);
5942                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5943            }
5944            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5945            if (app.isolated) {
5946                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5947            }
5948            app.kill(reason, true);
5949            handleAppDiedLocked(app, true, allowRestart);
5950            removeLruProcessLocked(app);
5951
5952            if (app.persistent && !app.isolated) {
5953                if (!callerWillRestart) {
5954                    addAppLocked(app.info, false, null /* ABI override */);
5955                } else {
5956                    needRestart = true;
5957                }
5958            }
5959        } else {
5960            mRemovedProcesses.add(app);
5961        }
5962
5963        return needRestart;
5964    }
5965
5966    private final void processStartTimedOutLocked(ProcessRecord app) {
5967        final int pid = app.pid;
5968        boolean gone = false;
5969        synchronized (mPidsSelfLocked) {
5970            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5971            if (knownApp != null && knownApp.thread == null) {
5972                mPidsSelfLocked.remove(pid);
5973                gone = true;
5974            }
5975        }
5976
5977        if (gone) {
5978            Slog.w(TAG, "Process " + app + " failed to attach");
5979            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5980                    pid, app.uid, app.processName);
5981            mProcessNames.remove(app.processName, app.uid);
5982            mIsolatedProcesses.remove(app.uid);
5983            if (mHeavyWeightProcess == app) {
5984                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5985                        mHeavyWeightProcess.userId, 0));
5986                mHeavyWeightProcess = null;
5987            }
5988            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5989            if (app.isolated) {
5990                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5991            }
5992            // Take care of any launching providers waiting for this process.
5993            checkAppInLaunchingProvidersLocked(app, true);
5994            // Take care of any services that are waiting for the process.
5995            mServices.processStartTimedOutLocked(app);
5996            app.kill("start timeout", true);
5997            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5998                Slog.w(TAG, "Unattached app died before backup, skipping");
5999                try {
6000                    IBackupManager bm = IBackupManager.Stub.asInterface(
6001                            ServiceManager.getService(Context.BACKUP_SERVICE));
6002                    bm.agentDisconnected(app.info.packageName);
6003                } catch (RemoteException e) {
6004                    // Can't happen; the backup manager is local
6005                }
6006            }
6007            if (isPendingBroadcastProcessLocked(pid)) {
6008                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6009                skipPendingBroadcastLocked(pid);
6010            }
6011        } else {
6012            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6013        }
6014    }
6015
6016    private final boolean attachApplicationLocked(IApplicationThread thread,
6017            int pid) {
6018
6019        // Find the application record that is being attached...  either via
6020        // the pid if we are running in multiple processes, or just pull the
6021        // next app record if we are emulating process with anonymous threads.
6022        ProcessRecord app;
6023        if (pid != MY_PID && pid >= 0) {
6024            synchronized (mPidsSelfLocked) {
6025                app = mPidsSelfLocked.get(pid);
6026            }
6027        } else {
6028            app = null;
6029        }
6030
6031        if (app == null) {
6032            Slog.w(TAG, "No pending application record for pid " + pid
6033                    + " (IApplicationThread " + thread + "); dropping process");
6034            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6035            if (pid > 0 && pid != MY_PID) {
6036                Process.killProcessQuiet(pid);
6037                //TODO: Process.killProcessGroup(app.info.uid, pid);
6038            } else {
6039                try {
6040                    thread.scheduleExit();
6041                } catch (Exception e) {
6042                    // Ignore exceptions.
6043                }
6044            }
6045            return false;
6046        }
6047
6048        // If this application record is still attached to a previous
6049        // process, clean it up now.
6050        if (app.thread != null) {
6051            handleAppDiedLocked(app, true, true);
6052        }
6053
6054        // Tell the process all about itself.
6055
6056        if (localLOGV) Slog.v(
6057                TAG, "Binding process pid " + pid + " to record " + app);
6058
6059        final String processName = app.processName;
6060        try {
6061            AppDeathRecipient adr = new AppDeathRecipient(
6062                    app, pid, thread);
6063            thread.asBinder().linkToDeath(adr, 0);
6064            app.deathRecipient = adr;
6065        } catch (RemoteException e) {
6066            app.resetPackageList(mProcessStats);
6067            startProcessLocked(app, "link fail", processName);
6068            return false;
6069        }
6070
6071        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6072
6073        app.makeActive(thread, mProcessStats);
6074        app.curAdj = app.setAdj = -100;
6075        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6076        app.forcingToForeground = null;
6077        updateProcessForegroundLocked(app, false, false);
6078        app.hasShownUi = false;
6079        app.debugging = false;
6080        app.cached = false;
6081
6082        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6083
6084        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6085        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6086
6087        if (!normalMode) {
6088            Slog.i(TAG, "Launching preboot mode app: " + app);
6089        }
6090
6091        if (localLOGV) Slog.v(
6092            TAG, "New app record " + app
6093            + " thread=" + thread.asBinder() + " pid=" + pid);
6094        try {
6095            int testMode = IApplicationThread.DEBUG_OFF;
6096            if (mDebugApp != null && mDebugApp.equals(processName)) {
6097                testMode = mWaitForDebugger
6098                    ? IApplicationThread.DEBUG_WAIT
6099                    : IApplicationThread.DEBUG_ON;
6100                app.debugging = true;
6101                if (mDebugTransient) {
6102                    mDebugApp = mOrigDebugApp;
6103                    mWaitForDebugger = mOrigWaitForDebugger;
6104                }
6105            }
6106            String profileFile = app.instrumentationProfileFile;
6107            ParcelFileDescriptor profileFd = null;
6108            int samplingInterval = 0;
6109            boolean profileAutoStop = false;
6110            if (mProfileApp != null && mProfileApp.equals(processName)) {
6111                mProfileProc = app;
6112                profileFile = mProfileFile;
6113                profileFd = mProfileFd;
6114                samplingInterval = mSamplingInterval;
6115                profileAutoStop = mAutoStopProfiler;
6116            }
6117            boolean enableOpenGlTrace = false;
6118            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6119                enableOpenGlTrace = true;
6120                mOpenGlTraceApp = null;
6121            }
6122
6123            // If the app is being launched for restore or full backup, set it up specially
6124            boolean isRestrictedBackupMode = false;
6125            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6126                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6127                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6128                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6129            }
6130
6131            ensurePackageDexOpt(app.instrumentationInfo != null
6132                    ? app.instrumentationInfo.packageName
6133                    : app.info.packageName);
6134            if (app.instrumentationClass != null) {
6135                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6136            }
6137            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6138                    + processName + " with config " + mConfiguration);
6139            ApplicationInfo appInfo = app.instrumentationInfo != null
6140                    ? app.instrumentationInfo : app.info;
6141            app.compat = compatibilityInfoForPackageLocked(appInfo);
6142            if (profileFd != null) {
6143                profileFd = profileFd.dup();
6144            }
6145            ProfilerInfo profilerInfo = profileFile == null ? null
6146                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6147            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6148                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6149                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6150                    isRestrictedBackupMode || !normalMode, app.persistent,
6151                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6152                    mCoreSettingsObserver.getCoreSettingsLocked());
6153            updateLruProcessLocked(app, false, null);
6154            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6155        } catch (Exception e) {
6156            // todo: Yikes!  What should we do?  For now we will try to
6157            // start another process, but that could easily get us in
6158            // an infinite loop of restarting processes...
6159            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6160
6161            app.resetPackageList(mProcessStats);
6162            app.unlinkDeathRecipient();
6163            startProcessLocked(app, "bind fail", processName);
6164            return false;
6165        }
6166
6167        // Remove this record from the list of starting applications.
6168        mPersistentStartingProcesses.remove(app);
6169        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6170                "Attach application locked removing on hold: " + app);
6171        mProcessesOnHold.remove(app);
6172
6173        boolean badApp = false;
6174        boolean didSomething = false;
6175
6176        // See if the top visible activity is waiting to run in this process...
6177        if (normalMode) {
6178            try {
6179                if (mStackSupervisor.attachApplicationLocked(app)) {
6180                    didSomething = true;
6181                }
6182            } catch (Exception e) {
6183                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6184                badApp = true;
6185            }
6186        }
6187
6188        // Find any services that should be running in this process...
6189        if (!badApp) {
6190            try {
6191                didSomething |= mServices.attachApplicationLocked(app, processName);
6192            } catch (Exception e) {
6193                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6194                badApp = true;
6195            }
6196        }
6197
6198        // Check if a next-broadcast receiver is in this process...
6199        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6200            try {
6201                didSomething |= sendPendingBroadcastsLocked(app);
6202            } catch (Exception e) {
6203                // If the app died trying to launch the receiver we declare it 'bad'
6204                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6205                badApp = true;
6206            }
6207        }
6208
6209        // Check whether the next backup agent is in this process...
6210        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6211            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6212            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6213            try {
6214                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6215                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6216                        mBackupTarget.backupMode);
6217            } catch (Exception e) {
6218                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6219                badApp = true;
6220            }
6221        }
6222
6223        if (badApp) {
6224            app.kill("error during init", true);
6225            handleAppDiedLocked(app, false, true);
6226            return false;
6227        }
6228
6229        if (!didSomething) {
6230            updateOomAdjLocked();
6231        }
6232
6233        return true;
6234    }
6235
6236    @Override
6237    public final void attachApplication(IApplicationThread thread) {
6238        synchronized (this) {
6239            int callingPid = Binder.getCallingPid();
6240            final long origId = Binder.clearCallingIdentity();
6241            attachApplicationLocked(thread, callingPid);
6242            Binder.restoreCallingIdentity(origId);
6243        }
6244    }
6245
6246    @Override
6247    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6248        final long origId = Binder.clearCallingIdentity();
6249        synchronized (this) {
6250            ActivityStack stack = ActivityRecord.getStackLocked(token);
6251            if (stack != null) {
6252                ActivityRecord r =
6253                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6254                if (stopProfiling) {
6255                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6256                        try {
6257                            mProfileFd.close();
6258                        } catch (IOException e) {
6259                        }
6260                        clearProfilerLocked();
6261                    }
6262                }
6263            }
6264        }
6265        Binder.restoreCallingIdentity(origId);
6266    }
6267
6268    void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6269        mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6270                finishBooting? 1 : 0, enableScreen ? 1 : 0));
6271    }
6272
6273    void enableScreenAfterBoot() {
6274        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6275                SystemClock.uptimeMillis());
6276        mWindowManager.enableScreenAfterBoot();
6277
6278        synchronized (this) {
6279            updateEventDispatchingLocked();
6280        }
6281    }
6282
6283    @Override
6284    public void showBootMessage(final CharSequence msg, final boolean always) {
6285        enforceNotIsolatedCaller("showBootMessage");
6286        mWindowManager.showBootMessage(msg, always);
6287    }
6288
6289    @Override
6290    public void keyguardWaitingForActivityDrawn() {
6291        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6292        final long token = Binder.clearCallingIdentity();
6293        try {
6294            synchronized (this) {
6295                if (DEBUG_LOCKSCREEN) logLockScreen("");
6296                mWindowManager.keyguardWaitingForActivityDrawn();
6297                if (mLockScreenShown) {
6298                    mLockScreenShown = false;
6299                    comeOutOfSleepIfNeededLocked();
6300                }
6301            }
6302        } finally {
6303            Binder.restoreCallingIdentity(token);
6304        }
6305    }
6306
6307    final void finishBooting() {
6308        synchronized (this) {
6309            if (!mBootAnimationComplete) {
6310                mCallFinishBooting = true;
6311                return;
6312            }
6313            mCallFinishBooting = false;
6314        }
6315
6316        // Register receivers to handle package update events
6317        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6318
6319        // Let system services know.
6320        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6321
6322        synchronized (this) {
6323            // Ensure that any processes we had put on hold are now started
6324            // up.
6325            final int NP = mProcessesOnHold.size();
6326            if (NP > 0) {
6327                ArrayList<ProcessRecord> procs =
6328                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6329                for (int ip=0; ip<NP; ip++) {
6330                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6331                            + procs.get(ip));
6332                    startProcessLocked(procs.get(ip), "on-hold", null);
6333                }
6334            }
6335
6336            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6337                // Start looking for apps that are abusing wake locks.
6338                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6339                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6340                // Tell anyone interested that we are done booting!
6341                SystemProperties.set("sys.boot_completed", "1");
6342
6343                // And trigger dev.bootcomplete if we are not showing encryption progress
6344                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6345                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6346                    SystemProperties.set("dev.bootcomplete", "1");
6347                }
6348                for (int i=0; i<mStartedUsers.size(); i++) {
6349                    UserStartedState uss = mStartedUsers.valueAt(i);
6350                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6351                        uss.mState = UserStartedState.STATE_RUNNING;
6352                        final int userId = mStartedUsers.keyAt(i);
6353                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6354                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6355                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6356                        broadcastIntentLocked(null, null, intent, null,
6357                                new IIntentReceiver.Stub() {
6358                                    @Override
6359                                    public void performReceive(Intent intent, int resultCode,
6360                                            String data, Bundle extras, boolean ordered,
6361                                            boolean sticky, int sendingUser) {
6362                                        synchronized (ActivityManagerService.this) {
6363                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6364                                                    true, false);
6365                                        }
6366                                    }
6367                                },
6368                                0, null, null,
6369                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6370                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6371                                userId);
6372                    }
6373                }
6374                scheduleStartProfilesLocked();
6375            }
6376        }
6377    }
6378
6379    @Override
6380    public void bootAnimationComplete() {
6381        final boolean callFinishBooting;
6382        synchronized (this) {
6383            callFinishBooting = mCallFinishBooting;
6384            mBootAnimationComplete = true;
6385        }
6386        if (callFinishBooting) {
6387            finishBooting();
6388        }
6389    }
6390
6391    final void ensureBootCompleted() {
6392        boolean booting;
6393        boolean enableScreen;
6394        synchronized (this) {
6395            booting = mBooting;
6396            mBooting = false;
6397            enableScreen = !mBooted;
6398            mBooted = true;
6399        }
6400
6401        if (booting) {
6402            finishBooting();
6403        }
6404
6405        if (enableScreen) {
6406            enableScreenAfterBoot();
6407        }
6408    }
6409
6410    @Override
6411    public final void activityResumed(IBinder token) {
6412        final long origId = Binder.clearCallingIdentity();
6413        synchronized(this) {
6414            ActivityStack stack = ActivityRecord.getStackLocked(token);
6415            if (stack != null) {
6416                ActivityRecord.activityResumedLocked(token);
6417            }
6418        }
6419        Binder.restoreCallingIdentity(origId);
6420    }
6421
6422    @Override
6423    public final void activityPaused(IBinder token) {
6424        final long origId = Binder.clearCallingIdentity();
6425        synchronized(this) {
6426            ActivityStack stack = ActivityRecord.getStackLocked(token);
6427            if (stack != null) {
6428                stack.activityPausedLocked(token, false);
6429            }
6430        }
6431        Binder.restoreCallingIdentity(origId);
6432    }
6433
6434    @Override
6435    public final void activityStopped(IBinder token, Bundle icicle,
6436            PersistableBundle persistentState, CharSequence description) {
6437        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6438
6439        // Refuse possible leaked file descriptors
6440        if (icicle != null && icicle.hasFileDescriptors()) {
6441            throw new IllegalArgumentException("File descriptors passed in Bundle");
6442        }
6443
6444        final long origId = Binder.clearCallingIdentity();
6445
6446        synchronized (this) {
6447            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6448            if (r != null) {
6449                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6450            }
6451        }
6452
6453        trimApplications();
6454
6455        Binder.restoreCallingIdentity(origId);
6456    }
6457
6458    @Override
6459    public final void activityDestroyed(IBinder token) {
6460        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6461        synchronized (this) {
6462            ActivityStack stack = ActivityRecord.getStackLocked(token);
6463            if (stack != null) {
6464                stack.activityDestroyedLocked(token);
6465            }
6466        }
6467    }
6468
6469    @Override
6470    public final void backgroundResourcesReleased(IBinder token) {
6471        final long origId = Binder.clearCallingIdentity();
6472        try {
6473            synchronized (this) {
6474                ActivityStack stack = ActivityRecord.getStackLocked(token);
6475                if (stack != null) {
6476                    stack.backgroundResourcesReleased(token);
6477                }
6478            }
6479        } finally {
6480            Binder.restoreCallingIdentity(origId);
6481        }
6482    }
6483
6484    @Override
6485    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6486        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6487    }
6488
6489    @Override
6490    public final void notifyEnterAnimationComplete(IBinder token) {
6491        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6492    }
6493
6494    @Override
6495    public String getCallingPackage(IBinder token) {
6496        synchronized (this) {
6497            ActivityRecord r = getCallingRecordLocked(token);
6498            return r != null ? r.info.packageName : null;
6499        }
6500    }
6501
6502    @Override
6503    public ComponentName getCallingActivity(IBinder token) {
6504        synchronized (this) {
6505            ActivityRecord r = getCallingRecordLocked(token);
6506            return r != null ? r.intent.getComponent() : null;
6507        }
6508    }
6509
6510    private ActivityRecord getCallingRecordLocked(IBinder token) {
6511        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6512        if (r == null) {
6513            return null;
6514        }
6515        return r.resultTo;
6516    }
6517
6518    @Override
6519    public ComponentName getActivityClassForToken(IBinder token) {
6520        synchronized(this) {
6521            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6522            if (r == null) {
6523                return null;
6524            }
6525            return r.intent.getComponent();
6526        }
6527    }
6528
6529    @Override
6530    public String getPackageForToken(IBinder token) {
6531        synchronized(this) {
6532            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6533            if (r == null) {
6534                return null;
6535            }
6536            return r.packageName;
6537        }
6538    }
6539
6540    @Override
6541    public IIntentSender getIntentSender(int type,
6542            String packageName, IBinder token, String resultWho,
6543            int requestCode, Intent[] intents, String[] resolvedTypes,
6544            int flags, Bundle options, int userId) {
6545        enforceNotIsolatedCaller("getIntentSender");
6546        // Refuse possible leaked file descriptors
6547        if (intents != null) {
6548            if (intents.length < 1) {
6549                throw new IllegalArgumentException("Intents array length must be >= 1");
6550            }
6551            for (int i=0; i<intents.length; i++) {
6552                Intent intent = intents[i];
6553                if (intent != null) {
6554                    if (intent.hasFileDescriptors()) {
6555                        throw new IllegalArgumentException("File descriptors passed in Intent");
6556                    }
6557                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6558                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6559                        throw new IllegalArgumentException(
6560                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6561                    }
6562                    intents[i] = new Intent(intent);
6563                }
6564            }
6565            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6566                throw new IllegalArgumentException(
6567                        "Intent array length does not match resolvedTypes length");
6568            }
6569        }
6570        if (options != null) {
6571            if (options.hasFileDescriptors()) {
6572                throw new IllegalArgumentException("File descriptors passed in options");
6573            }
6574        }
6575
6576        synchronized(this) {
6577            int callingUid = Binder.getCallingUid();
6578            int origUserId = userId;
6579            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6580                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6581                    ALLOW_NON_FULL, "getIntentSender", null);
6582            if (origUserId == UserHandle.USER_CURRENT) {
6583                // We don't want to evaluate this until the pending intent is
6584                // actually executed.  However, we do want to always do the
6585                // security checking for it above.
6586                userId = UserHandle.USER_CURRENT;
6587            }
6588            try {
6589                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6590                    int uid = AppGlobals.getPackageManager()
6591                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6592                    if (!UserHandle.isSameApp(callingUid, uid)) {
6593                        String msg = "Permission Denial: getIntentSender() from pid="
6594                            + Binder.getCallingPid()
6595                            + ", uid=" + Binder.getCallingUid()
6596                            + ", (need uid=" + uid + ")"
6597                            + " is not allowed to send as package " + packageName;
6598                        Slog.w(TAG, msg);
6599                        throw new SecurityException(msg);
6600                    }
6601                }
6602
6603                return getIntentSenderLocked(type, packageName, callingUid, userId,
6604                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6605
6606            } catch (RemoteException e) {
6607                throw new SecurityException(e);
6608            }
6609        }
6610    }
6611
6612    IIntentSender getIntentSenderLocked(int type, String packageName,
6613            int callingUid, int userId, IBinder token, String resultWho,
6614            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6615            Bundle options) {
6616        if (DEBUG_MU)
6617            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6618        ActivityRecord activity = null;
6619        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6620            activity = ActivityRecord.isInStackLocked(token);
6621            if (activity == null) {
6622                return null;
6623            }
6624            if (activity.finishing) {
6625                return null;
6626            }
6627        }
6628
6629        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6630        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6631        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6632        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6633                |PendingIntent.FLAG_UPDATE_CURRENT);
6634
6635        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6636                type, packageName, activity, resultWho,
6637                requestCode, intents, resolvedTypes, flags, options, userId);
6638        WeakReference<PendingIntentRecord> ref;
6639        ref = mIntentSenderRecords.get(key);
6640        PendingIntentRecord rec = ref != null ? ref.get() : null;
6641        if (rec != null) {
6642            if (!cancelCurrent) {
6643                if (updateCurrent) {
6644                    if (rec.key.requestIntent != null) {
6645                        rec.key.requestIntent.replaceExtras(intents != null ?
6646                                intents[intents.length - 1] : null);
6647                    }
6648                    if (intents != null) {
6649                        intents[intents.length-1] = rec.key.requestIntent;
6650                        rec.key.allIntents = intents;
6651                        rec.key.allResolvedTypes = resolvedTypes;
6652                    } else {
6653                        rec.key.allIntents = null;
6654                        rec.key.allResolvedTypes = null;
6655                    }
6656                }
6657                return rec;
6658            }
6659            rec.canceled = true;
6660            mIntentSenderRecords.remove(key);
6661        }
6662        if (noCreate) {
6663            return rec;
6664        }
6665        rec = new PendingIntentRecord(this, key, callingUid);
6666        mIntentSenderRecords.put(key, rec.ref);
6667        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6668            if (activity.pendingResults == null) {
6669                activity.pendingResults
6670                        = new HashSet<WeakReference<PendingIntentRecord>>();
6671            }
6672            activity.pendingResults.add(rec.ref);
6673        }
6674        return rec;
6675    }
6676
6677    @Override
6678    public void cancelIntentSender(IIntentSender sender) {
6679        if (!(sender instanceof PendingIntentRecord)) {
6680            return;
6681        }
6682        synchronized(this) {
6683            PendingIntentRecord rec = (PendingIntentRecord)sender;
6684            try {
6685                int uid = AppGlobals.getPackageManager()
6686                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6687                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6688                    String msg = "Permission Denial: cancelIntentSender() from pid="
6689                        + Binder.getCallingPid()
6690                        + ", uid=" + Binder.getCallingUid()
6691                        + " is not allowed to cancel packges "
6692                        + rec.key.packageName;
6693                    Slog.w(TAG, msg);
6694                    throw new SecurityException(msg);
6695                }
6696            } catch (RemoteException e) {
6697                throw new SecurityException(e);
6698            }
6699            cancelIntentSenderLocked(rec, true);
6700        }
6701    }
6702
6703    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6704        rec.canceled = true;
6705        mIntentSenderRecords.remove(rec.key);
6706        if (cleanActivity && rec.key.activity != null) {
6707            rec.key.activity.pendingResults.remove(rec.ref);
6708        }
6709    }
6710
6711    @Override
6712    public String getPackageForIntentSender(IIntentSender pendingResult) {
6713        if (!(pendingResult instanceof PendingIntentRecord)) {
6714            return null;
6715        }
6716        try {
6717            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6718            return res.key.packageName;
6719        } catch (ClassCastException e) {
6720        }
6721        return null;
6722    }
6723
6724    @Override
6725    public int getUidForIntentSender(IIntentSender sender) {
6726        if (sender instanceof PendingIntentRecord) {
6727            try {
6728                PendingIntentRecord res = (PendingIntentRecord)sender;
6729                return res.uid;
6730            } catch (ClassCastException e) {
6731            }
6732        }
6733        return -1;
6734    }
6735
6736    @Override
6737    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6738        if (!(pendingResult instanceof PendingIntentRecord)) {
6739            return false;
6740        }
6741        try {
6742            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6743            if (res.key.allIntents == null) {
6744                return false;
6745            }
6746            for (int i=0; i<res.key.allIntents.length; i++) {
6747                Intent intent = res.key.allIntents[i];
6748                if (intent.getPackage() != null && intent.getComponent() != null) {
6749                    return false;
6750                }
6751            }
6752            return true;
6753        } catch (ClassCastException e) {
6754        }
6755        return false;
6756    }
6757
6758    @Override
6759    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6760        if (!(pendingResult instanceof PendingIntentRecord)) {
6761            return false;
6762        }
6763        try {
6764            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6765            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6766                return true;
6767            }
6768            return false;
6769        } catch (ClassCastException e) {
6770        }
6771        return false;
6772    }
6773
6774    @Override
6775    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6776        if (!(pendingResult instanceof PendingIntentRecord)) {
6777            return null;
6778        }
6779        try {
6780            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6781            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6782        } catch (ClassCastException e) {
6783        }
6784        return null;
6785    }
6786
6787    @Override
6788    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6789        if (!(pendingResult instanceof PendingIntentRecord)) {
6790            return null;
6791        }
6792        try {
6793            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6794            Intent intent = res.key.requestIntent;
6795            if (intent != null) {
6796                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6797                        || res.lastTagPrefix.equals(prefix))) {
6798                    return res.lastTag;
6799                }
6800                res.lastTagPrefix = prefix;
6801                StringBuilder sb = new StringBuilder(128);
6802                if (prefix != null) {
6803                    sb.append(prefix);
6804                }
6805                if (intent.getAction() != null) {
6806                    sb.append(intent.getAction());
6807                } else if (intent.getComponent() != null) {
6808                    intent.getComponent().appendShortString(sb);
6809                } else {
6810                    sb.append("?");
6811                }
6812                return res.lastTag = sb.toString();
6813            }
6814        } catch (ClassCastException e) {
6815        }
6816        return null;
6817    }
6818
6819    @Override
6820    public void setProcessLimit(int max) {
6821        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6822                "setProcessLimit()");
6823        synchronized (this) {
6824            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6825            mProcessLimitOverride = max;
6826        }
6827        trimApplications();
6828    }
6829
6830    @Override
6831    public int getProcessLimit() {
6832        synchronized (this) {
6833            return mProcessLimitOverride;
6834        }
6835    }
6836
6837    void foregroundTokenDied(ForegroundToken token) {
6838        synchronized (ActivityManagerService.this) {
6839            synchronized (mPidsSelfLocked) {
6840                ForegroundToken cur
6841                    = mForegroundProcesses.get(token.pid);
6842                if (cur != token) {
6843                    return;
6844                }
6845                mForegroundProcesses.remove(token.pid);
6846                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6847                if (pr == null) {
6848                    return;
6849                }
6850                pr.forcingToForeground = null;
6851                updateProcessForegroundLocked(pr, false, false);
6852            }
6853            updateOomAdjLocked();
6854        }
6855    }
6856
6857    @Override
6858    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6859        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6860                "setProcessForeground()");
6861        synchronized(this) {
6862            boolean changed = false;
6863
6864            synchronized (mPidsSelfLocked) {
6865                ProcessRecord pr = mPidsSelfLocked.get(pid);
6866                if (pr == null && isForeground) {
6867                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6868                    return;
6869                }
6870                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6871                if (oldToken != null) {
6872                    oldToken.token.unlinkToDeath(oldToken, 0);
6873                    mForegroundProcesses.remove(pid);
6874                    if (pr != null) {
6875                        pr.forcingToForeground = null;
6876                    }
6877                    changed = true;
6878                }
6879                if (isForeground && token != null) {
6880                    ForegroundToken newToken = new ForegroundToken() {
6881                        @Override
6882                        public void binderDied() {
6883                            foregroundTokenDied(this);
6884                        }
6885                    };
6886                    newToken.pid = pid;
6887                    newToken.token = token;
6888                    try {
6889                        token.linkToDeath(newToken, 0);
6890                        mForegroundProcesses.put(pid, newToken);
6891                        pr.forcingToForeground = token;
6892                        changed = true;
6893                    } catch (RemoteException e) {
6894                        // If the process died while doing this, we will later
6895                        // do the cleanup with the process death link.
6896                    }
6897                }
6898            }
6899
6900            if (changed) {
6901                updateOomAdjLocked();
6902            }
6903        }
6904    }
6905
6906    // =========================================================
6907    // PERMISSIONS
6908    // =========================================================
6909
6910    static class PermissionController extends IPermissionController.Stub {
6911        ActivityManagerService mActivityManagerService;
6912        PermissionController(ActivityManagerService activityManagerService) {
6913            mActivityManagerService = activityManagerService;
6914        }
6915
6916        @Override
6917        public boolean checkPermission(String permission, int pid, int uid) {
6918            return mActivityManagerService.checkPermission(permission, pid,
6919                    uid) == PackageManager.PERMISSION_GRANTED;
6920        }
6921    }
6922
6923    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6924        @Override
6925        public int checkComponentPermission(String permission, int pid, int uid,
6926                int owningUid, boolean exported) {
6927            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6928                    owningUid, exported);
6929        }
6930
6931        @Override
6932        public Object getAMSLock() {
6933            return ActivityManagerService.this;
6934        }
6935    }
6936
6937    /**
6938     * This can be called with or without the global lock held.
6939     */
6940    int checkComponentPermission(String permission, int pid, int uid,
6941            int owningUid, boolean exported) {
6942        // We might be performing an operation on behalf of an indirect binder
6943        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6944        // client identity accordingly before proceeding.
6945        Identity tlsIdentity = sCallerIdentity.get();
6946        if (tlsIdentity != null) {
6947            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6948                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6949            uid = tlsIdentity.uid;
6950            pid = tlsIdentity.pid;
6951        }
6952
6953        if (pid == MY_PID) {
6954            return PackageManager.PERMISSION_GRANTED;
6955        }
6956
6957        return ActivityManager.checkComponentPermission(permission, uid,
6958                owningUid, exported);
6959    }
6960
6961    /**
6962     * As the only public entry point for permissions checking, this method
6963     * can enforce the semantic that requesting a check on a null global
6964     * permission is automatically denied.  (Internally a null permission
6965     * string is used when calling {@link #checkComponentPermission} in cases
6966     * when only uid-based security is needed.)
6967     *
6968     * This can be called with or without the global lock held.
6969     */
6970    @Override
6971    public int checkPermission(String permission, int pid, int uid) {
6972        if (permission == null) {
6973            return PackageManager.PERMISSION_DENIED;
6974        }
6975        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6976    }
6977
6978    /**
6979     * Binder IPC calls go through the public entry point.
6980     * This can be called with or without the global lock held.
6981     */
6982    int checkCallingPermission(String permission) {
6983        return checkPermission(permission,
6984                Binder.getCallingPid(),
6985                UserHandle.getAppId(Binder.getCallingUid()));
6986    }
6987
6988    /**
6989     * This can be called with or without the global lock held.
6990     */
6991    void enforceCallingPermission(String permission, String func) {
6992        if (checkCallingPermission(permission)
6993                == PackageManager.PERMISSION_GRANTED) {
6994            return;
6995        }
6996
6997        String msg = "Permission Denial: " + func + " from pid="
6998                + Binder.getCallingPid()
6999                + ", uid=" + Binder.getCallingUid()
7000                + " requires " + permission;
7001        Slog.w(TAG, msg);
7002        throw new SecurityException(msg);
7003    }
7004
7005    /**
7006     * Determine if UID is holding permissions required to access {@link Uri} in
7007     * the given {@link ProviderInfo}. Final permission checking is always done
7008     * in {@link ContentProvider}.
7009     */
7010    private final boolean checkHoldingPermissionsLocked(
7011            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7012        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7013                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7014        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7015            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7016                    != PERMISSION_GRANTED) {
7017                return false;
7018            }
7019        }
7020        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7021    }
7022
7023    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7024            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7025        if (pi.applicationInfo.uid == uid) {
7026            return true;
7027        } else if (!pi.exported) {
7028            return false;
7029        }
7030
7031        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7032        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7033        try {
7034            // check if target holds top-level <provider> permissions
7035            if (!readMet && pi.readPermission != null && considerUidPermissions
7036                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7037                readMet = true;
7038            }
7039            if (!writeMet && pi.writePermission != null && considerUidPermissions
7040                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7041                writeMet = true;
7042            }
7043
7044            // track if unprotected read/write is allowed; any denied
7045            // <path-permission> below removes this ability
7046            boolean allowDefaultRead = pi.readPermission == null;
7047            boolean allowDefaultWrite = pi.writePermission == null;
7048
7049            // check if target holds any <path-permission> that match uri
7050            final PathPermission[] pps = pi.pathPermissions;
7051            if (pps != null) {
7052                final String path = grantUri.uri.getPath();
7053                int i = pps.length;
7054                while (i > 0 && (!readMet || !writeMet)) {
7055                    i--;
7056                    PathPermission pp = pps[i];
7057                    if (pp.match(path)) {
7058                        if (!readMet) {
7059                            final String pprperm = pp.getReadPermission();
7060                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7061                                    + pprperm + " for " + pp.getPath()
7062                                    + ": match=" + pp.match(path)
7063                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7064                            if (pprperm != null) {
7065                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7066                                        == PERMISSION_GRANTED) {
7067                                    readMet = true;
7068                                } else {
7069                                    allowDefaultRead = false;
7070                                }
7071                            }
7072                        }
7073                        if (!writeMet) {
7074                            final String ppwperm = pp.getWritePermission();
7075                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7076                                    + ppwperm + " for " + pp.getPath()
7077                                    + ": match=" + pp.match(path)
7078                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7079                            if (ppwperm != null) {
7080                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7081                                        == PERMISSION_GRANTED) {
7082                                    writeMet = true;
7083                                } else {
7084                                    allowDefaultWrite = false;
7085                                }
7086                            }
7087                        }
7088                    }
7089                }
7090            }
7091
7092            // grant unprotected <provider> read/write, if not blocked by
7093            // <path-permission> above
7094            if (allowDefaultRead) readMet = true;
7095            if (allowDefaultWrite) writeMet = true;
7096
7097        } catch (RemoteException e) {
7098            return false;
7099        }
7100
7101        return readMet && writeMet;
7102    }
7103
7104    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7105        ProviderInfo pi = null;
7106        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7107        if (cpr != null) {
7108            pi = cpr.info;
7109        } else {
7110            try {
7111                pi = AppGlobals.getPackageManager().resolveContentProvider(
7112                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7113            } catch (RemoteException ex) {
7114            }
7115        }
7116        return pi;
7117    }
7118
7119    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7120        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7121        if (targetUris != null) {
7122            return targetUris.get(grantUri);
7123        }
7124        return null;
7125    }
7126
7127    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7128            String targetPkg, int targetUid, GrantUri grantUri) {
7129        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7130        if (targetUris == null) {
7131            targetUris = Maps.newArrayMap();
7132            mGrantedUriPermissions.put(targetUid, targetUris);
7133        }
7134
7135        UriPermission perm = targetUris.get(grantUri);
7136        if (perm == null) {
7137            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7138            targetUris.put(grantUri, perm);
7139        }
7140
7141        return perm;
7142    }
7143
7144    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7145            final int modeFlags) {
7146        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7147        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7148                : UriPermission.STRENGTH_OWNED;
7149
7150        // Root gets to do everything.
7151        if (uid == 0) {
7152            return true;
7153        }
7154
7155        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7156        if (perms == null) return false;
7157
7158        // First look for exact match
7159        final UriPermission exactPerm = perms.get(grantUri);
7160        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7161            return true;
7162        }
7163
7164        // No exact match, look for prefixes
7165        final int N = perms.size();
7166        for (int i = 0; i < N; i++) {
7167            final UriPermission perm = perms.valueAt(i);
7168            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7169                    && perm.getStrength(modeFlags) >= minStrength) {
7170                return true;
7171            }
7172        }
7173
7174        return false;
7175    }
7176
7177    /**
7178     * @param uri This uri must NOT contain an embedded userId.
7179     * @param userId The userId in which the uri is to be resolved.
7180     */
7181    @Override
7182    public int checkUriPermission(Uri uri, int pid, int uid,
7183            final int modeFlags, int userId) {
7184        enforceNotIsolatedCaller("checkUriPermission");
7185
7186        // Another redirected-binder-call permissions check as in
7187        // {@link checkComponentPermission}.
7188        Identity tlsIdentity = sCallerIdentity.get();
7189        if (tlsIdentity != null) {
7190            uid = tlsIdentity.uid;
7191            pid = tlsIdentity.pid;
7192        }
7193
7194        // Our own process gets to do everything.
7195        if (pid == MY_PID) {
7196            return PackageManager.PERMISSION_GRANTED;
7197        }
7198        synchronized (this) {
7199            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7200                    ? PackageManager.PERMISSION_GRANTED
7201                    : PackageManager.PERMISSION_DENIED;
7202        }
7203    }
7204
7205    /**
7206     * Check if the targetPkg can be granted permission to access uri by
7207     * the callingUid using the given modeFlags.  Throws a security exception
7208     * if callingUid is not allowed to do this.  Returns the uid of the target
7209     * if the URI permission grant should be performed; returns -1 if it is not
7210     * needed (for example targetPkg already has permission to access the URI).
7211     * If you already know the uid of the target, you can supply it in
7212     * lastTargetUid else set that to -1.
7213     */
7214    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7215            final int modeFlags, int lastTargetUid) {
7216        if (!Intent.isAccessUriMode(modeFlags)) {
7217            return -1;
7218        }
7219
7220        if (targetPkg != null) {
7221            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7222                    "Checking grant " + targetPkg + " permission to " + grantUri);
7223        }
7224
7225        final IPackageManager pm = AppGlobals.getPackageManager();
7226
7227        // If this is not a content: uri, we can't do anything with it.
7228        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7229            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7230                    "Can't grant URI permission for non-content URI: " + grantUri);
7231            return -1;
7232        }
7233
7234        final String authority = grantUri.uri.getAuthority();
7235        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7236        if (pi == null) {
7237            Slog.w(TAG, "No content provider found for permission check: " +
7238                    grantUri.uri.toSafeString());
7239            return -1;
7240        }
7241
7242        int targetUid = lastTargetUid;
7243        if (targetUid < 0 && targetPkg != null) {
7244            try {
7245                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7246                if (targetUid < 0) {
7247                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7248                            "Can't grant URI permission no uid for: " + targetPkg);
7249                    return -1;
7250                }
7251            } catch (RemoteException ex) {
7252                return -1;
7253            }
7254        }
7255
7256        if (targetUid >= 0) {
7257            // First...  does the target actually need this permission?
7258            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7259                // No need to grant the target this permission.
7260                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7261                        "Target " + targetPkg + " already has full permission to " + grantUri);
7262                return -1;
7263            }
7264        } else {
7265            // First...  there is no target package, so can anyone access it?
7266            boolean allowed = pi.exported;
7267            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7268                if (pi.readPermission != null) {
7269                    allowed = false;
7270                }
7271            }
7272            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7273                if (pi.writePermission != null) {
7274                    allowed = false;
7275                }
7276            }
7277            if (allowed) {
7278                return -1;
7279            }
7280        }
7281
7282        /* There is a special cross user grant if:
7283         * - The target is on another user.
7284         * - Apps on the current user can access the uri without any uid permissions.
7285         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7286         * grant uri permissions.
7287         */
7288        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7289                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7290                modeFlags, false /*without considering the uid permissions*/);
7291
7292        // Second...  is the provider allowing granting of URI permissions?
7293        if (!specialCrossUserGrant) {
7294            if (!pi.grantUriPermissions) {
7295                throw new SecurityException("Provider " + pi.packageName
7296                        + "/" + pi.name
7297                        + " does not allow granting of Uri permissions (uri "
7298                        + grantUri + ")");
7299            }
7300            if (pi.uriPermissionPatterns != null) {
7301                final int N = pi.uriPermissionPatterns.length;
7302                boolean allowed = false;
7303                for (int i=0; i<N; i++) {
7304                    if (pi.uriPermissionPatterns[i] != null
7305                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7306                        allowed = true;
7307                        break;
7308                    }
7309                }
7310                if (!allowed) {
7311                    throw new SecurityException("Provider " + pi.packageName
7312                            + "/" + pi.name
7313                            + " does not allow granting of permission to path of Uri "
7314                            + grantUri);
7315                }
7316            }
7317        }
7318
7319        // Third...  does the caller itself have permission to access
7320        // this uri?
7321        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7322            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7323                // Require they hold a strong enough Uri permission
7324                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7325                    throw new SecurityException("Uid " + callingUid
7326                            + " does not have permission to uri " + grantUri);
7327                }
7328            }
7329        }
7330        return targetUid;
7331    }
7332
7333    /**
7334     * @param uri This uri must NOT contain an embedded userId.
7335     * @param userId The userId in which the uri is to be resolved.
7336     */
7337    @Override
7338    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7339            final int modeFlags, int userId) {
7340        enforceNotIsolatedCaller("checkGrantUriPermission");
7341        synchronized(this) {
7342            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7343                    new GrantUri(userId, uri, false), modeFlags, -1);
7344        }
7345    }
7346
7347    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7348            final int modeFlags, UriPermissionOwner owner) {
7349        if (!Intent.isAccessUriMode(modeFlags)) {
7350            return;
7351        }
7352
7353        // So here we are: the caller has the assumed permission
7354        // to the uri, and the target doesn't.  Let's now give this to
7355        // the target.
7356
7357        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7358                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7359
7360        final String authority = grantUri.uri.getAuthority();
7361        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7362        if (pi == null) {
7363            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7364            return;
7365        }
7366
7367        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7368            grantUri.prefix = true;
7369        }
7370        final UriPermission perm = findOrCreateUriPermissionLocked(
7371                pi.packageName, targetPkg, targetUid, grantUri);
7372        perm.grantModes(modeFlags, owner);
7373    }
7374
7375    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7376            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7377        if (targetPkg == null) {
7378            throw new NullPointerException("targetPkg");
7379        }
7380        int targetUid;
7381        final IPackageManager pm = AppGlobals.getPackageManager();
7382        try {
7383            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7384        } catch (RemoteException ex) {
7385            return;
7386        }
7387
7388        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7389                targetUid);
7390        if (targetUid < 0) {
7391            return;
7392        }
7393
7394        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7395                owner);
7396    }
7397
7398    static class NeededUriGrants extends ArrayList<GrantUri> {
7399        final String targetPkg;
7400        final int targetUid;
7401        final int flags;
7402
7403        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7404            this.targetPkg = targetPkg;
7405            this.targetUid = targetUid;
7406            this.flags = flags;
7407        }
7408    }
7409
7410    /**
7411     * Like checkGrantUriPermissionLocked, but takes an Intent.
7412     */
7413    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7414            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7415        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7416                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7417                + " clip=" + (intent != null ? intent.getClipData() : null)
7418                + " from " + intent + "; flags=0x"
7419                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7420
7421        if (targetPkg == null) {
7422            throw new NullPointerException("targetPkg");
7423        }
7424
7425        if (intent == null) {
7426            return null;
7427        }
7428        Uri data = intent.getData();
7429        ClipData clip = intent.getClipData();
7430        if (data == null && clip == null) {
7431            return null;
7432        }
7433        // Default userId for uris in the intent (if they don't specify it themselves)
7434        int contentUserHint = intent.getContentUserHint();
7435        if (contentUserHint == UserHandle.USER_CURRENT) {
7436            contentUserHint = UserHandle.getUserId(callingUid);
7437        }
7438        final IPackageManager pm = AppGlobals.getPackageManager();
7439        int targetUid;
7440        if (needed != null) {
7441            targetUid = needed.targetUid;
7442        } else {
7443            try {
7444                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7445            } catch (RemoteException ex) {
7446                return null;
7447            }
7448            if (targetUid < 0) {
7449                if (DEBUG_URI_PERMISSION) {
7450                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7451                            + " on user " + targetUserId);
7452                }
7453                return null;
7454            }
7455        }
7456        if (data != null) {
7457            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7458            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7459                    targetUid);
7460            if (targetUid > 0) {
7461                if (needed == null) {
7462                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7463                }
7464                needed.add(grantUri);
7465            }
7466        }
7467        if (clip != null) {
7468            for (int i=0; i<clip.getItemCount(); i++) {
7469                Uri uri = clip.getItemAt(i).getUri();
7470                if (uri != null) {
7471                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7472                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7473                            targetUid);
7474                    if (targetUid > 0) {
7475                        if (needed == null) {
7476                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7477                        }
7478                        needed.add(grantUri);
7479                    }
7480                } else {
7481                    Intent clipIntent = clip.getItemAt(i).getIntent();
7482                    if (clipIntent != null) {
7483                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7484                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7485                        if (newNeeded != null) {
7486                            needed = newNeeded;
7487                        }
7488                    }
7489                }
7490            }
7491        }
7492
7493        return needed;
7494    }
7495
7496    /**
7497     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7498     */
7499    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7500            UriPermissionOwner owner) {
7501        if (needed != null) {
7502            for (int i=0; i<needed.size(); i++) {
7503                GrantUri grantUri = needed.get(i);
7504                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7505                        grantUri, needed.flags, owner);
7506            }
7507        }
7508    }
7509
7510    void grantUriPermissionFromIntentLocked(int callingUid,
7511            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7512        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7513                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7514        if (needed == null) {
7515            return;
7516        }
7517
7518        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7519    }
7520
7521    /**
7522     * @param uri This uri must NOT contain an embedded userId.
7523     * @param userId The userId in which the uri is to be resolved.
7524     */
7525    @Override
7526    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7527            final int modeFlags, int userId) {
7528        enforceNotIsolatedCaller("grantUriPermission");
7529        GrantUri grantUri = new GrantUri(userId, uri, false);
7530        synchronized(this) {
7531            final ProcessRecord r = getRecordForAppLocked(caller);
7532            if (r == null) {
7533                throw new SecurityException("Unable to find app for caller "
7534                        + caller
7535                        + " when granting permission to uri " + grantUri);
7536            }
7537            if (targetPkg == null) {
7538                throw new IllegalArgumentException("null target");
7539            }
7540            if (grantUri == null) {
7541                throw new IllegalArgumentException("null uri");
7542            }
7543
7544            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7545                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7546                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7547                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7548
7549            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7550                    UserHandle.getUserId(r.uid));
7551        }
7552    }
7553
7554    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7555        if (perm.modeFlags == 0) {
7556            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7557                    perm.targetUid);
7558            if (perms != null) {
7559                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7560                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7561
7562                perms.remove(perm.uri);
7563                if (perms.isEmpty()) {
7564                    mGrantedUriPermissions.remove(perm.targetUid);
7565                }
7566            }
7567        }
7568    }
7569
7570    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7571        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7572
7573        final IPackageManager pm = AppGlobals.getPackageManager();
7574        final String authority = grantUri.uri.getAuthority();
7575        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7576        if (pi == null) {
7577            Slog.w(TAG, "No content provider found for permission revoke: "
7578                    + grantUri.toSafeString());
7579            return;
7580        }
7581
7582        // Does the caller have this permission on the URI?
7583        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7584            // If they don't have direct access to the URI, then revoke any
7585            // ownerless URI permissions that have been granted to them.
7586            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7587            if (perms != null) {
7588                boolean persistChanged = false;
7589                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7590                    final UriPermission perm = it.next();
7591                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7592                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7593                        if (DEBUG_URI_PERMISSION)
7594                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7595                                    " permission to " + perm.uri);
7596                        persistChanged |= perm.revokeModes(
7597                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7598                        if (perm.modeFlags == 0) {
7599                            it.remove();
7600                        }
7601                    }
7602                }
7603                if (perms.isEmpty()) {
7604                    mGrantedUriPermissions.remove(callingUid);
7605                }
7606                if (persistChanged) {
7607                    schedulePersistUriGrants();
7608                }
7609            }
7610            return;
7611        }
7612
7613        boolean persistChanged = false;
7614
7615        // Go through all of the permissions and remove any that match.
7616        int N = mGrantedUriPermissions.size();
7617        for (int i = 0; i < N; i++) {
7618            final int targetUid = mGrantedUriPermissions.keyAt(i);
7619            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7620
7621            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7622                final UriPermission perm = it.next();
7623                if (perm.uri.sourceUserId == grantUri.sourceUserId
7624                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7625                    if (DEBUG_URI_PERMISSION)
7626                        Slog.v(TAG,
7627                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7628                    persistChanged |= perm.revokeModes(
7629                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7630                    if (perm.modeFlags == 0) {
7631                        it.remove();
7632                    }
7633                }
7634            }
7635
7636            if (perms.isEmpty()) {
7637                mGrantedUriPermissions.remove(targetUid);
7638                N--;
7639                i--;
7640            }
7641        }
7642
7643        if (persistChanged) {
7644            schedulePersistUriGrants();
7645        }
7646    }
7647
7648    /**
7649     * @param uri This uri must NOT contain an embedded userId.
7650     * @param userId The userId in which the uri is to be resolved.
7651     */
7652    @Override
7653    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7654            int userId) {
7655        enforceNotIsolatedCaller("revokeUriPermission");
7656        synchronized(this) {
7657            final ProcessRecord r = getRecordForAppLocked(caller);
7658            if (r == null) {
7659                throw new SecurityException("Unable to find app for caller "
7660                        + caller
7661                        + " when revoking permission to uri " + uri);
7662            }
7663            if (uri == null) {
7664                Slog.w(TAG, "revokeUriPermission: null uri");
7665                return;
7666            }
7667
7668            if (!Intent.isAccessUriMode(modeFlags)) {
7669                return;
7670            }
7671
7672            final IPackageManager pm = AppGlobals.getPackageManager();
7673            final String authority = uri.getAuthority();
7674            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7675            if (pi == null) {
7676                Slog.w(TAG, "No content provider found for permission revoke: "
7677                        + uri.toSafeString());
7678                return;
7679            }
7680
7681            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7682        }
7683    }
7684
7685    /**
7686     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7687     * given package.
7688     *
7689     * @param packageName Package name to match, or {@code null} to apply to all
7690     *            packages.
7691     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7692     *            to all users.
7693     * @param persistable If persistable grants should be removed.
7694     */
7695    private void removeUriPermissionsForPackageLocked(
7696            String packageName, int userHandle, boolean persistable) {
7697        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7698            throw new IllegalArgumentException("Must narrow by either package or user");
7699        }
7700
7701        boolean persistChanged = false;
7702
7703        int N = mGrantedUriPermissions.size();
7704        for (int i = 0; i < N; i++) {
7705            final int targetUid = mGrantedUriPermissions.keyAt(i);
7706            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7707
7708            // Only inspect grants matching user
7709            if (userHandle == UserHandle.USER_ALL
7710                    || userHandle == UserHandle.getUserId(targetUid)) {
7711                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7712                    final UriPermission perm = it.next();
7713
7714                    // Only inspect grants matching package
7715                    if (packageName == null || perm.sourcePkg.equals(packageName)
7716                            || perm.targetPkg.equals(packageName)) {
7717                        persistChanged |= perm.revokeModes(persistable
7718                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7719
7720                        // Only remove when no modes remain; any persisted grants
7721                        // will keep this alive.
7722                        if (perm.modeFlags == 0) {
7723                            it.remove();
7724                        }
7725                    }
7726                }
7727
7728                if (perms.isEmpty()) {
7729                    mGrantedUriPermissions.remove(targetUid);
7730                    N--;
7731                    i--;
7732                }
7733            }
7734        }
7735
7736        if (persistChanged) {
7737            schedulePersistUriGrants();
7738        }
7739    }
7740
7741    @Override
7742    public IBinder newUriPermissionOwner(String name) {
7743        enforceNotIsolatedCaller("newUriPermissionOwner");
7744        synchronized(this) {
7745            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7746            return owner.getExternalTokenLocked();
7747        }
7748    }
7749
7750    /**
7751     * @param uri This uri must NOT contain an embedded userId.
7752     * @param sourceUserId The userId in which the uri is to be resolved.
7753     * @param targetUserId The userId of the app that receives the grant.
7754     */
7755    @Override
7756    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7757            final int modeFlags, int sourceUserId, int targetUserId) {
7758        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7759                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7760        synchronized(this) {
7761            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7762            if (owner == null) {
7763                throw new IllegalArgumentException("Unknown owner: " + token);
7764            }
7765            if (fromUid != Binder.getCallingUid()) {
7766                if (Binder.getCallingUid() != Process.myUid()) {
7767                    // Only system code can grant URI permissions on behalf
7768                    // of other users.
7769                    throw new SecurityException("nice try");
7770                }
7771            }
7772            if (targetPkg == null) {
7773                throw new IllegalArgumentException("null target");
7774            }
7775            if (uri == null) {
7776                throw new IllegalArgumentException("null uri");
7777            }
7778
7779            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7780                    modeFlags, owner, targetUserId);
7781        }
7782    }
7783
7784    /**
7785     * @param uri This uri must NOT contain an embedded userId.
7786     * @param userId The userId in which the uri is to be resolved.
7787     */
7788    @Override
7789    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7790        synchronized(this) {
7791            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7792            if (owner == null) {
7793                throw new IllegalArgumentException("Unknown owner: " + token);
7794            }
7795
7796            if (uri == null) {
7797                owner.removeUriPermissionsLocked(mode);
7798            } else {
7799                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7800            }
7801        }
7802    }
7803
7804    private void schedulePersistUriGrants() {
7805        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7806            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7807                    10 * DateUtils.SECOND_IN_MILLIS);
7808        }
7809    }
7810
7811    private void writeGrantedUriPermissions() {
7812        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7813
7814        // Snapshot permissions so we can persist without lock
7815        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7816        synchronized (this) {
7817            final int size = mGrantedUriPermissions.size();
7818            for (int i = 0; i < size; i++) {
7819                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7820                for (UriPermission perm : perms.values()) {
7821                    if (perm.persistedModeFlags != 0) {
7822                        persist.add(perm.snapshot());
7823                    }
7824                }
7825            }
7826        }
7827
7828        FileOutputStream fos = null;
7829        try {
7830            fos = mGrantFile.startWrite();
7831
7832            XmlSerializer out = new FastXmlSerializer();
7833            out.setOutput(fos, "utf-8");
7834            out.startDocument(null, true);
7835            out.startTag(null, TAG_URI_GRANTS);
7836            for (UriPermission.Snapshot perm : persist) {
7837                out.startTag(null, TAG_URI_GRANT);
7838                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7839                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7840                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7841                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7842                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7843                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7844                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7845                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7846                out.endTag(null, TAG_URI_GRANT);
7847            }
7848            out.endTag(null, TAG_URI_GRANTS);
7849            out.endDocument();
7850
7851            mGrantFile.finishWrite(fos);
7852        } catch (IOException e) {
7853            if (fos != null) {
7854                mGrantFile.failWrite(fos);
7855            }
7856        }
7857    }
7858
7859    private void readGrantedUriPermissionsLocked() {
7860        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7861
7862        final long now = System.currentTimeMillis();
7863
7864        FileInputStream fis = null;
7865        try {
7866            fis = mGrantFile.openRead();
7867            final XmlPullParser in = Xml.newPullParser();
7868            in.setInput(fis, null);
7869
7870            int type;
7871            while ((type = in.next()) != END_DOCUMENT) {
7872                final String tag = in.getName();
7873                if (type == START_TAG) {
7874                    if (TAG_URI_GRANT.equals(tag)) {
7875                        final int sourceUserId;
7876                        final int targetUserId;
7877                        final int userHandle = readIntAttribute(in,
7878                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7879                        if (userHandle != UserHandle.USER_NULL) {
7880                            // For backwards compatibility.
7881                            sourceUserId = userHandle;
7882                            targetUserId = userHandle;
7883                        } else {
7884                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7885                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7886                        }
7887                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7888                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7889                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7890                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7891                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7892                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7893
7894                        // Sanity check that provider still belongs to source package
7895                        final ProviderInfo pi = getProviderInfoLocked(
7896                                uri.getAuthority(), sourceUserId);
7897                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7898                            int targetUid = -1;
7899                            try {
7900                                targetUid = AppGlobals.getPackageManager()
7901                                        .getPackageUid(targetPkg, targetUserId);
7902                            } catch (RemoteException e) {
7903                            }
7904                            if (targetUid != -1) {
7905                                final UriPermission perm = findOrCreateUriPermissionLocked(
7906                                        sourcePkg, targetPkg, targetUid,
7907                                        new GrantUri(sourceUserId, uri, prefix));
7908                                perm.initPersistedModes(modeFlags, createdTime);
7909                            }
7910                        } else {
7911                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7912                                    + " but instead found " + pi);
7913                        }
7914                    }
7915                }
7916            }
7917        } catch (FileNotFoundException e) {
7918            // Missing grants is okay
7919        } catch (IOException e) {
7920            Slog.wtf(TAG, "Failed reading Uri grants", e);
7921        } catch (XmlPullParserException e) {
7922            Slog.wtf(TAG, "Failed reading Uri grants", e);
7923        } finally {
7924            IoUtils.closeQuietly(fis);
7925        }
7926    }
7927
7928    /**
7929     * @param uri This uri must NOT contain an embedded userId.
7930     * @param userId The userId in which the uri is to be resolved.
7931     */
7932    @Override
7933    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7934        enforceNotIsolatedCaller("takePersistableUriPermission");
7935
7936        Preconditions.checkFlagsArgument(modeFlags,
7937                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7938
7939        synchronized (this) {
7940            final int callingUid = Binder.getCallingUid();
7941            boolean persistChanged = false;
7942            GrantUri grantUri = new GrantUri(userId, uri, false);
7943
7944            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7945                    new GrantUri(userId, uri, false));
7946            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7947                    new GrantUri(userId, uri, true));
7948
7949            final boolean exactValid = (exactPerm != null)
7950                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7951            final boolean prefixValid = (prefixPerm != null)
7952                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7953
7954            if (!(exactValid || prefixValid)) {
7955                throw new SecurityException("No persistable permission grants found for UID "
7956                        + callingUid + " and Uri " + grantUri.toSafeString());
7957            }
7958
7959            if (exactValid) {
7960                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7961            }
7962            if (prefixValid) {
7963                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7964            }
7965
7966            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7967
7968            if (persistChanged) {
7969                schedulePersistUriGrants();
7970            }
7971        }
7972    }
7973
7974    /**
7975     * @param uri This uri must NOT contain an embedded userId.
7976     * @param userId The userId in which the uri is to be resolved.
7977     */
7978    @Override
7979    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7980        enforceNotIsolatedCaller("releasePersistableUriPermission");
7981
7982        Preconditions.checkFlagsArgument(modeFlags,
7983                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7984
7985        synchronized (this) {
7986            final int callingUid = Binder.getCallingUid();
7987            boolean persistChanged = false;
7988
7989            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7990                    new GrantUri(userId, uri, false));
7991            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7992                    new GrantUri(userId, uri, true));
7993            if (exactPerm == null && prefixPerm == null) {
7994                throw new SecurityException("No permission grants found for UID " + callingUid
7995                        + " and Uri " + uri.toSafeString());
7996            }
7997
7998            if (exactPerm != null) {
7999                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8000                removeUriPermissionIfNeededLocked(exactPerm);
8001            }
8002            if (prefixPerm != null) {
8003                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8004                removeUriPermissionIfNeededLocked(prefixPerm);
8005            }
8006
8007            if (persistChanged) {
8008                schedulePersistUriGrants();
8009            }
8010        }
8011    }
8012
8013    /**
8014     * Prune any older {@link UriPermission} for the given UID until outstanding
8015     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8016     *
8017     * @return if any mutations occured that require persisting.
8018     */
8019    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8020        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8021        if (perms == null) return false;
8022        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8023
8024        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8025        for (UriPermission perm : perms.values()) {
8026            if (perm.persistedModeFlags != 0) {
8027                persisted.add(perm);
8028            }
8029        }
8030
8031        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8032        if (trimCount <= 0) return false;
8033
8034        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8035        for (int i = 0; i < trimCount; i++) {
8036            final UriPermission perm = persisted.get(i);
8037
8038            if (DEBUG_URI_PERMISSION) {
8039                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8040            }
8041
8042            perm.releasePersistableModes(~0);
8043            removeUriPermissionIfNeededLocked(perm);
8044        }
8045
8046        return true;
8047    }
8048
8049    @Override
8050    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8051            String packageName, boolean incoming) {
8052        enforceNotIsolatedCaller("getPersistedUriPermissions");
8053        Preconditions.checkNotNull(packageName, "packageName");
8054
8055        final int callingUid = Binder.getCallingUid();
8056        final IPackageManager pm = AppGlobals.getPackageManager();
8057        try {
8058            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8059            if (packageUid != callingUid) {
8060                throw new SecurityException(
8061                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8062            }
8063        } catch (RemoteException e) {
8064            throw new SecurityException("Failed to verify package name ownership");
8065        }
8066
8067        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8068        synchronized (this) {
8069            if (incoming) {
8070                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8071                        callingUid);
8072                if (perms == null) {
8073                    Slog.w(TAG, "No permission grants found for " + packageName);
8074                } else {
8075                    for (UriPermission perm : perms.values()) {
8076                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8077                            result.add(perm.buildPersistedPublicApiObject());
8078                        }
8079                    }
8080                }
8081            } else {
8082                final int size = mGrantedUriPermissions.size();
8083                for (int i = 0; i < size; i++) {
8084                    final ArrayMap<GrantUri, UriPermission> perms =
8085                            mGrantedUriPermissions.valueAt(i);
8086                    for (UriPermission perm : perms.values()) {
8087                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8088                            result.add(perm.buildPersistedPublicApiObject());
8089                        }
8090                    }
8091                }
8092            }
8093        }
8094        return new ParceledListSlice<android.content.UriPermission>(result);
8095    }
8096
8097    @Override
8098    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8099        synchronized (this) {
8100            ProcessRecord app =
8101                who != null ? getRecordForAppLocked(who) : null;
8102            if (app == null) return;
8103
8104            Message msg = Message.obtain();
8105            msg.what = WAIT_FOR_DEBUGGER_MSG;
8106            msg.obj = app;
8107            msg.arg1 = waiting ? 1 : 0;
8108            mHandler.sendMessage(msg);
8109        }
8110    }
8111
8112    @Override
8113    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8114        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8115        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8116        outInfo.availMem = Process.getFreeMemory();
8117        outInfo.totalMem = Process.getTotalMemory();
8118        outInfo.threshold = homeAppMem;
8119        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8120        outInfo.hiddenAppThreshold = cachedAppMem;
8121        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8122                ProcessList.SERVICE_ADJ);
8123        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8124                ProcessList.VISIBLE_APP_ADJ);
8125        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8126                ProcessList.FOREGROUND_APP_ADJ);
8127    }
8128
8129    // =========================================================
8130    // TASK MANAGEMENT
8131    // =========================================================
8132
8133    @Override
8134    public List<IAppTask> getAppTasks(String callingPackage) {
8135        int callingUid = Binder.getCallingUid();
8136        long ident = Binder.clearCallingIdentity();
8137
8138        synchronized(this) {
8139            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8140            try {
8141                if (localLOGV) Slog.v(TAG, "getAppTasks");
8142
8143                final int N = mRecentTasks.size();
8144                for (int i = 0; i < N; i++) {
8145                    TaskRecord tr = mRecentTasks.get(i);
8146                    // Skip tasks that do not match the caller.  We don't need to verify
8147                    // callingPackage, because we are also limiting to callingUid and know
8148                    // that will limit to the correct security sandbox.
8149                    if (tr.effectiveUid != callingUid) {
8150                        continue;
8151                    }
8152                    Intent intent = tr.getBaseIntent();
8153                    if (intent == null ||
8154                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8155                        continue;
8156                    }
8157                    ActivityManager.RecentTaskInfo taskInfo =
8158                            createRecentTaskInfoFromTaskRecord(tr);
8159                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8160                    list.add(taskImpl);
8161                }
8162            } finally {
8163                Binder.restoreCallingIdentity(ident);
8164            }
8165            return list;
8166        }
8167    }
8168
8169    @Override
8170    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8171        final int callingUid = Binder.getCallingUid();
8172        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8173
8174        synchronized(this) {
8175            if (localLOGV) Slog.v(
8176                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8177
8178            final boolean allowed = checkCallingPermission(
8179                    android.Manifest.permission.GET_TASKS)
8180                    == PackageManager.PERMISSION_GRANTED;
8181            if (!allowed) {
8182                Slog.w(TAG, "getTasks: caller " + callingUid
8183                        + " does not hold GET_TASKS; limiting output");
8184            }
8185
8186            // TODO: Improve with MRU list from all ActivityStacks.
8187            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8188        }
8189
8190        return list;
8191    }
8192
8193    TaskRecord getMostRecentTask() {
8194        return mRecentTasks.get(0);
8195    }
8196
8197    /**
8198     * Creates a new RecentTaskInfo from a TaskRecord.
8199     */
8200    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8201        // Update the task description to reflect any changes in the task stack
8202        tr.updateTaskDescription();
8203
8204        // Compose the recent task info
8205        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8206        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8207        rti.persistentId = tr.taskId;
8208        rti.baseIntent = new Intent(tr.getBaseIntent());
8209        rti.origActivity = tr.origActivity;
8210        rti.description = tr.lastDescription;
8211        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8212        rti.userId = tr.userId;
8213        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8214        rti.firstActiveTime = tr.firstActiveTime;
8215        rti.lastActiveTime = tr.lastActiveTime;
8216        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8217        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8218        return rti;
8219    }
8220
8221    @Override
8222    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8223        final int callingUid = Binder.getCallingUid();
8224        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8225                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8226
8227        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8228        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8229        synchronized (this) {
8230            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8231                    == PackageManager.PERMISSION_GRANTED;
8232            if (!allowed) {
8233                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8234                        + " does not hold GET_TASKS; limiting output");
8235            }
8236            final boolean detailed = checkCallingPermission(
8237                    android.Manifest.permission.GET_DETAILED_TASKS)
8238                    == PackageManager.PERMISSION_GRANTED;
8239
8240            final int N = mRecentTasks.size();
8241            ArrayList<ActivityManager.RecentTaskInfo> res
8242                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8243                            maxNum < N ? maxNum : N);
8244
8245            final Set<Integer> includedUsers;
8246            if (includeProfiles) {
8247                includedUsers = getProfileIdsLocked(userId);
8248            } else {
8249                includedUsers = new HashSet<Integer>();
8250            }
8251            includedUsers.add(Integer.valueOf(userId));
8252
8253            for (int i=0; i<N && maxNum > 0; i++) {
8254                TaskRecord tr = mRecentTasks.get(i);
8255                // Only add calling user or related users recent tasks
8256                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8257                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8258                    continue;
8259                }
8260
8261                // Return the entry if desired by the caller.  We always return
8262                // the first entry, because callers always expect this to be the
8263                // foreground app.  We may filter others if the caller has
8264                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8265                // we should exclude the entry.
8266
8267                if (i == 0
8268                        || withExcluded
8269                        || (tr.intent == null)
8270                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8271                                == 0)) {
8272                    if (!allowed) {
8273                        // If the caller doesn't have the GET_TASKS permission, then only
8274                        // allow them to see a small subset of tasks -- their own and home.
8275                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8276                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8277                            continue;
8278                        }
8279                    }
8280                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8281                        if (tr.stack != null && tr.stack.isHomeStack()) {
8282                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8283                            continue;
8284                        }
8285                    }
8286                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8287                        // Don't include auto remove tasks that are finished or finishing.
8288                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8289                                + tr);
8290                        continue;
8291                    }
8292                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8293                            && !tr.isAvailable) {
8294                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8295                        continue;
8296                    }
8297
8298                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8299                    if (!detailed) {
8300                        rti.baseIntent.replaceExtras((Bundle)null);
8301                    }
8302
8303                    res.add(rti);
8304                    maxNum--;
8305                }
8306            }
8307            return res;
8308        }
8309    }
8310
8311    private TaskRecord recentTaskForIdLocked(int id) {
8312        final int N = mRecentTasks.size();
8313            for (int i=0; i<N; i++) {
8314                TaskRecord tr = mRecentTasks.get(i);
8315                if (tr.taskId == id) {
8316                    return tr;
8317                }
8318            }
8319            return null;
8320    }
8321
8322    @Override
8323    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8324        synchronized (this) {
8325            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8326                    "getTaskThumbnail()");
8327            TaskRecord tr = recentTaskForIdLocked(id);
8328            if (tr != null) {
8329                return tr.getTaskThumbnailLocked();
8330            }
8331        }
8332        return null;
8333    }
8334
8335    @Override
8336    public int addAppTask(IBinder activityToken, Intent intent,
8337            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8338        final int callingUid = Binder.getCallingUid();
8339        final long callingIdent = Binder.clearCallingIdentity();
8340
8341        try {
8342            synchronized (this) {
8343                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8344                if (r == null) {
8345                    throw new IllegalArgumentException("Activity does not exist; token="
8346                            + activityToken);
8347                }
8348                ComponentName comp = intent.getComponent();
8349                if (comp == null) {
8350                    throw new IllegalArgumentException("Intent " + intent
8351                            + " must specify explicit component");
8352                }
8353                if (thumbnail.getWidth() != mThumbnailWidth
8354                        || thumbnail.getHeight() != mThumbnailHeight) {
8355                    throw new IllegalArgumentException("Bad thumbnail size: got "
8356                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8357                            + mThumbnailWidth + "x" + mThumbnailHeight);
8358                }
8359                if (intent.getSelector() != null) {
8360                    intent.setSelector(null);
8361                }
8362                if (intent.getSourceBounds() != null) {
8363                    intent.setSourceBounds(null);
8364                }
8365                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8366                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8367                        // The caller has added this as an auto-remove task...  that makes no
8368                        // sense, so turn off auto-remove.
8369                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8370                    }
8371                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8372                    // Must be a new task.
8373                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8374                }
8375                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8376                    mLastAddedTaskActivity = null;
8377                }
8378                ActivityInfo ainfo = mLastAddedTaskActivity;
8379                if (ainfo == null) {
8380                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8381                            comp, 0, UserHandle.getUserId(callingUid));
8382                    if (ainfo.applicationInfo.uid != callingUid) {
8383                        throw new SecurityException(
8384                                "Can't add task for another application: target uid="
8385                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8386                    }
8387                }
8388
8389                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8390                        intent, description);
8391
8392                int trimIdx = trimRecentsForTask(task, false);
8393                if (trimIdx >= 0) {
8394                    // If this would have caused a trim, then we'll abort because that
8395                    // means it would be added at the end of the list but then just removed.
8396                    return -1;
8397                }
8398
8399                final int N = mRecentTasks.size();
8400                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8401                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8402                    tr.removedFromRecents(mTaskPersister);
8403                }
8404
8405                task.inRecents = true;
8406                mRecentTasks.add(task);
8407                r.task.stack.addTask(task, false, false);
8408
8409                task.setLastThumbnail(thumbnail);
8410                task.freeLastThumbnail();
8411
8412                return task.taskId;
8413            }
8414        } finally {
8415            Binder.restoreCallingIdentity(callingIdent);
8416        }
8417    }
8418
8419    @Override
8420    public Point getAppTaskThumbnailSize() {
8421        synchronized (this) {
8422            return new Point(mThumbnailWidth,  mThumbnailHeight);
8423        }
8424    }
8425
8426    @Override
8427    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8428        synchronized (this) {
8429            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8430            if (r != null) {
8431                r.setTaskDescription(td);
8432                r.task.updateTaskDescription();
8433            }
8434        }
8435    }
8436
8437    @Override
8438    public Bitmap getTaskDescriptionIcon(String filename) {
8439        if (!FileUtils.isValidExtFilename(filename)
8440                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8441            throw new IllegalArgumentException("Bad filename: " + filename);
8442        }
8443        return mTaskPersister.getTaskDescriptionIcon(filename);
8444    }
8445
8446    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8447        mRecentTasks.remove(tr);
8448        tr.removedFromRecents(mTaskPersister);
8449        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8450        Intent baseIntent = new Intent(
8451                tr.intent != null ? tr.intent : tr.affinityIntent);
8452        ComponentName component = baseIntent.getComponent();
8453        if (component == null) {
8454            Slog.w(TAG, "Now component for base intent of task: " + tr);
8455            return;
8456        }
8457
8458        // Find any running services associated with this app.
8459        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8460
8461        if (killProcesses) {
8462            // Find any running processes associated with this app.
8463            final String pkg = component.getPackageName();
8464            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8465            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8466            for (int i=0; i<pmap.size(); i++) {
8467                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8468                for (int j=0; j<uids.size(); j++) {
8469                    ProcessRecord proc = uids.valueAt(j);
8470                    if (proc.userId != tr.userId) {
8471                        continue;
8472                    }
8473                    if (!proc.pkgList.containsKey(pkg)) {
8474                        continue;
8475                    }
8476                    procs.add(proc);
8477                }
8478            }
8479
8480            // Kill the running processes.
8481            for (int i=0; i<procs.size(); i++) {
8482                ProcessRecord pr = procs.get(i);
8483                if (pr == mHomeProcess) {
8484                    // Don't kill the home process along with tasks from the same package.
8485                    continue;
8486                }
8487                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8488                    pr.kill("remove task", true);
8489                } else {
8490                    pr.waitingToKill = "remove task";
8491                }
8492            }
8493        }
8494    }
8495
8496    /**
8497     * Removes the task with the specified task id.
8498     *
8499     * @param taskId Identifier of the task to be removed.
8500     * @param flags Additional operational flags.  May be 0 or
8501     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8502     * @return Returns true if the given task was found and removed.
8503     */
8504    private boolean removeTaskByIdLocked(int taskId, int flags) {
8505        TaskRecord tr = recentTaskForIdLocked(taskId);
8506        if (tr != null) {
8507            tr.removeTaskActivitiesLocked();
8508            cleanUpRemovedTaskLocked(tr, flags);
8509            if (tr.isPersistable) {
8510                notifyTaskPersisterLocked(null, true);
8511            }
8512            return true;
8513        }
8514        return false;
8515    }
8516
8517    @Override
8518    public boolean removeTask(int taskId, int flags) {
8519        synchronized (this) {
8520            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8521                    "removeTask()");
8522            long ident = Binder.clearCallingIdentity();
8523            try {
8524                return removeTaskByIdLocked(taskId, flags);
8525            } finally {
8526                Binder.restoreCallingIdentity(ident);
8527            }
8528        }
8529    }
8530
8531    /**
8532     * TODO: Add mController hook
8533     */
8534    @Override
8535    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8536        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8537                "moveTaskToFront()");
8538
8539        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8540        synchronized(this) {
8541            moveTaskToFrontLocked(taskId, flags, options);
8542        }
8543    }
8544
8545    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8546        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8547                Binder.getCallingUid(), -1, -1, "Task to front")) {
8548            ActivityOptions.abort(options);
8549            return;
8550        }
8551        final long origId = Binder.clearCallingIdentity();
8552        try {
8553            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8554            if (task == null) {
8555                return;
8556            }
8557            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8558                mStackSupervisor.showLockTaskToast();
8559                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8560                return;
8561            }
8562            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8563            if (prev != null && prev.isRecentsActivity()) {
8564                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8565            }
8566            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8567        } finally {
8568            Binder.restoreCallingIdentity(origId);
8569        }
8570        ActivityOptions.abort(options);
8571    }
8572
8573    @Override
8574    public void moveTaskToBack(int taskId) {
8575        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8576                "moveTaskToBack()");
8577
8578        synchronized(this) {
8579            TaskRecord tr = recentTaskForIdLocked(taskId);
8580            if (tr != null) {
8581                if (tr == mStackSupervisor.mLockTaskModeTask) {
8582                    mStackSupervisor.showLockTaskToast();
8583                    return;
8584                }
8585                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8586                ActivityStack stack = tr.stack;
8587                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8588                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8589                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8590                        return;
8591                    }
8592                }
8593                final long origId = Binder.clearCallingIdentity();
8594                try {
8595                    stack.moveTaskToBackLocked(taskId, null);
8596                } finally {
8597                    Binder.restoreCallingIdentity(origId);
8598                }
8599            }
8600        }
8601    }
8602
8603    /**
8604     * Moves an activity, and all of the other activities within the same task, to the bottom
8605     * of the history stack.  The activity's order within the task is unchanged.
8606     *
8607     * @param token A reference to the activity we wish to move
8608     * @param nonRoot If false then this only works if the activity is the root
8609     *                of a task; if true it will work for any activity in a task.
8610     * @return Returns true if the move completed, false if not.
8611     */
8612    @Override
8613    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8614        enforceNotIsolatedCaller("moveActivityTaskToBack");
8615        synchronized(this) {
8616            final long origId = Binder.clearCallingIdentity();
8617            try {
8618                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8619                if (taskId >= 0) {
8620                    if ((mStackSupervisor.mLockTaskModeTask != null)
8621                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8622                        mStackSupervisor.showLockTaskToast();
8623                        return false;
8624                    }
8625                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8626                }
8627            } finally {
8628                Binder.restoreCallingIdentity(origId);
8629            }
8630        }
8631        return false;
8632    }
8633
8634    @Override
8635    public void moveTaskBackwards(int task) {
8636        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8637                "moveTaskBackwards()");
8638
8639        synchronized(this) {
8640            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8641                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8642                return;
8643            }
8644            final long origId = Binder.clearCallingIdentity();
8645            moveTaskBackwardsLocked(task);
8646            Binder.restoreCallingIdentity(origId);
8647        }
8648    }
8649
8650    private final void moveTaskBackwardsLocked(int task) {
8651        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8652    }
8653
8654    @Override
8655    public IBinder getHomeActivityToken() throws RemoteException {
8656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8657                "getHomeActivityToken()");
8658        synchronized (this) {
8659            return mStackSupervisor.getHomeActivityToken();
8660        }
8661    }
8662
8663    @Override
8664    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8665            IActivityContainerCallback callback) throws RemoteException {
8666        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8667                "createActivityContainer()");
8668        synchronized (this) {
8669            if (parentActivityToken == null) {
8670                throw new IllegalArgumentException("parent token must not be null");
8671            }
8672            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8673            if (r == null) {
8674                return null;
8675            }
8676            if (callback == null) {
8677                throw new IllegalArgumentException("callback must not be null");
8678            }
8679            return mStackSupervisor.createActivityContainer(r, callback);
8680        }
8681    }
8682
8683    @Override
8684    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8685        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8686                "deleteActivityContainer()");
8687        synchronized (this) {
8688            mStackSupervisor.deleteActivityContainer(container);
8689        }
8690    }
8691
8692    @Override
8693    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8694            throws RemoteException {
8695        synchronized (this) {
8696            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8697            if (stack != null) {
8698                return stack.mActivityContainer;
8699            }
8700            return null;
8701        }
8702    }
8703
8704    @Override
8705    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8706        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8707                "moveTaskToStack()");
8708        if (stackId == HOME_STACK_ID) {
8709            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8710                    new RuntimeException("here").fillInStackTrace());
8711        }
8712        synchronized (this) {
8713            long ident = Binder.clearCallingIdentity();
8714            try {
8715                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8716                        + stackId + " toTop=" + toTop);
8717                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8718            } finally {
8719                Binder.restoreCallingIdentity(ident);
8720            }
8721        }
8722    }
8723
8724    @Override
8725    public void resizeStack(int stackBoxId, Rect bounds) {
8726        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8727                "resizeStackBox()");
8728        long ident = Binder.clearCallingIdentity();
8729        try {
8730            mWindowManager.resizeStack(stackBoxId, bounds);
8731        } finally {
8732            Binder.restoreCallingIdentity(ident);
8733        }
8734    }
8735
8736    @Override
8737    public List<StackInfo> getAllStackInfos() {
8738        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8739                "getAllStackInfos()");
8740        long ident = Binder.clearCallingIdentity();
8741        try {
8742            synchronized (this) {
8743                return mStackSupervisor.getAllStackInfosLocked();
8744            }
8745        } finally {
8746            Binder.restoreCallingIdentity(ident);
8747        }
8748    }
8749
8750    @Override
8751    public StackInfo getStackInfo(int stackId) {
8752        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8753                "getStackInfo()");
8754        long ident = Binder.clearCallingIdentity();
8755        try {
8756            synchronized (this) {
8757                return mStackSupervisor.getStackInfoLocked(stackId);
8758            }
8759        } finally {
8760            Binder.restoreCallingIdentity(ident);
8761        }
8762    }
8763
8764    @Override
8765    public boolean isInHomeStack(int taskId) {
8766        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8767                "getStackInfo()");
8768        long ident = Binder.clearCallingIdentity();
8769        try {
8770            synchronized (this) {
8771                TaskRecord tr = recentTaskForIdLocked(taskId);
8772                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8773            }
8774        } finally {
8775            Binder.restoreCallingIdentity(ident);
8776        }
8777    }
8778
8779    @Override
8780    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8781        synchronized(this) {
8782            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8783        }
8784    }
8785
8786    private boolean isLockTaskAuthorized(String pkg) {
8787        final DevicePolicyManager dpm = (DevicePolicyManager)
8788                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8789        try {
8790            int uid = mContext.getPackageManager().getPackageUid(pkg,
8791                    Binder.getCallingUserHandle().getIdentifier());
8792            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8793        } catch (NameNotFoundException e) {
8794            return false;
8795        }
8796    }
8797
8798    void startLockTaskMode(TaskRecord task) {
8799        final String pkg;
8800        synchronized (this) {
8801            pkg = task.intent.getComponent().getPackageName();
8802        }
8803        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8804        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8805            final TaskRecord taskRecord = task;
8806            mHandler.post(new Runnable() {
8807                @Override
8808                public void run() {
8809                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8810                }
8811            });
8812            return;
8813        }
8814        long ident = Binder.clearCallingIdentity();
8815        try {
8816            synchronized (this) {
8817                // Since we lost lock on task, make sure it is still there.
8818                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8819                if (task != null) {
8820                    if (!isSystemInitiated
8821                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8822                        throw new IllegalArgumentException("Invalid task, not in foreground");
8823                    }
8824                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8825                }
8826            }
8827        } finally {
8828            Binder.restoreCallingIdentity(ident);
8829        }
8830    }
8831
8832    @Override
8833    public void startLockTaskMode(int taskId) {
8834        final TaskRecord task;
8835        long ident = Binder.clearCallingIdentity();
8836        try {
8837            synchronized (this) {
8838                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8839            }
8840        } finally {
8841            Binder.restoreCallingIdentity(ident);
8842        }
8843        if (task != null) {
8844            startLockTaskMode(task);
8845        }
8846    }
8847
8848    @Override
8849    public void startLockTaskMode(IBinder token) {
8850        final TaskRecord task;
8851        long ident = Binder.clearCallingIdentity();
8852        try {
8853            synchronized (this) {
8854                final ActivityRecord r = ActivityRecord.forToken(token);
8855                if (r == null) {
8856                    return;
8857                }
8858                task = r.task;
8859            }
8860        } finally {
8861            Binder.restoreCallingIdentity(ident);
8862        }
8863        if (task != null) {
8864            startLockTaskMode(task);
8865        }
8866    }
8867
8868    @Override
8869    public void startLockTaskModeOnCurrent() throws RemoteException {
8870        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8871                "startLockTaskModeOnCurrent");
8872        ActivityRecord r = null;
8873        synchronized (this) {
8874            r = mStackSupervisor.topRunningActivityLocked();
8875        }
8876        startLockTaskMode(r.task);
8877    }
8878
8879    @Override
8880    public void stopLockTaskMode() {
8881        // Verify that the user matches the package of the intent for the TaskRecord
8882        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8883        // and stopLockTaskMode.
8884        final int callingUid = Binder.getCallingUid();
8885        if (callingUid != Process.SYSTEM_UID) {
8886            try {
8887                String pkg =
8888                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8889                int uid = mContext.getPackageManager().getPackageUid(pkg,
8890                        Binder.getCallingUserHandle().getIdentifier());
8891                if (uid != callingUid) {
8892                    throw new SecurityException("Invalid uid, expected " + uid);
8893                }
8894            } catch (NameNotFoundException e) {
8895                Log.d(TAG, "stopLockTaskMode " + e);
8896                return;
8897            }
8898        }
8899        long ident = Binder.clearCallingIdentity();
8900        try {
8901            Log.d(TAG, "stopLockTaskMode");
8902            // Stop lock task
8903            synchronized (this) {
8904                mStackSupervisor.setLockTaskModeLocked(null, false);
8905            }
8906        } finally {
8907            Binder.restoreCallingIdentity(ident);
8908        }
8909    }
8910
8911    @Override
8912    public void stopLockTaskModeOnCurrent() throws RemoteException {
8913        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8914                "stopLockTaskModeOnCurrent");
8915        long ident = Binder.clearCallingIdentity();
8916        try {
8917            stopLockTaskMode();
8918        } finally {
8919            Binder.restoreCallingIdentity(ident);
8920        }
8921    }
8922
8923    @Override
8924    public boolean isInLockTaskMode() {
8925        synchronized (this) {
8926            return mStackSupervisor.isInLockTaskMode();
8927        }
8928    }
8929
8930    // =========================================================
8931    // CONTENT PROVIDERS
8932    // =========================================================
8933
8934    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8935        List<ProviderInfo> providers = null;
8936        try {
8937            providers = AppGlobals.getPackageManager().
8938                queryContentProviders(app.processName, app.uid,
8939                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8940        } catch (RemoteException ex) {
8941        }
8942        if (DEBUG_MU)
8943            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8944        int userId = app.userId;
8945        if (providers != null) {
8946            int N = providers.size();
8947            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8948            for (int i=0; i<N; i++) {
8949                ProviderInfo cpi =
8950                    (ProviderInfo)providers.get(i);
8951                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8952                        cpi.name, cpi.flags);
8953                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8954                    // This is a singleton provider, but a user besides the
8955                    // default user is asking to initialize a process it runs
8956                    // in...  well, no, it doesn't actually run in this process,
8957                    // it runs in the process of the default user.  Get rid of it.
8958                    providers.remove(i);
8959                    N--;
8960                    i--;
8961                    continue;
8962                }
8963
8964                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8965                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8966                if (cpr == null) {
8967                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8968                    mProviderMap.putProviderByClass(comp, cpr);
8969                }
8970                if (DEBUG_MU)
8971                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8972                app.pubProviders.put(cpi.name, cpr);
8973                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8974                    // Don't add this if it is a platform component that is marked
8975                    // to run in multiple processes, because this is actually
8976                    // part of the framework so doesn't make sense to track as a
8977                    // separate apk in the process.
8978                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8979                            mProcessStats);
8980                }
8981                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8982            }
8983        }
8984        return providers;
8985    }
8986
8987    /**
8988     * Check if {@link ProcessRecord} has a possible chance at accessing the
8989     * given {@link ProviderInfo}. Final permission checking is always done
8990     * in {@link ContentProvider}.
8991     */
8992    private final String checkContentProviderPermissionLocked(
8993            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8994        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8995        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8996        boolean checkedGrants = false;
8997        if (checkUser) {
8998            // Looking for cross-user grants before enforcing the typical cross-users permissions
8999            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9000            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9001                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9002                    return null;
9003                }
9004                checkedGrants = true;
9005            }
9006            userId = handleIncomingUser(callingPid, callingUid, userId,
9007                    false, ALLOW_NON_FULL,
9008                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9009            if (userId != tmpTargetUserId) {
9010                // When we actually went to determine the final targer user ID, this ended
9011                // up different than our initial check for the authority.  This is because
9012                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9013                // SELF.  So we need to re-check the grants again.
9014                checkedGrants = false;
9015            }
9016        }
9017        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9018                cpi.applicationInfo.uid, cpi.exported)
9019                == PackageManager.PERMISSION_GRANTED) {
9020            return null;
9021        }
9022        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9023                cpi.applicationInfo.uid, cpi.exported)
9024                == PackageManager.PERMISSION_GRANTED) {
9025            return null;
9026        }
9027
9028        PathPermission[] pps = cpi.pathPermissions;
9029        if (pps != null) {
9030            int i = pps.length;
9031            while (i > 0) {
9032                i--;
9033                PathPermission pp = pps[i];
9034                String pprperm = pp.getReadPermission();
9035                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9036                        cpi.applicationInfo.uid, cpi.exported)
9037                        == PackageManager.PERMISSION_GRANTED) {
9038                    return null;
9039                }
9040                String ppwperm = pp.getWritePermission();
9041                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9042                        cpi.applicationInfo.uid, cpi.exported)
9043                        == PackageManager.PERMISSION_GRANTED) {
9044                    return null;
9045                }
9046            }
9047        }
9048        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9049            return null;
9050        }
9051
9052        String msg;
9053        if (!cpi.exported) {
9054            msg = "Permission Denial: opening provider " + cpi.name
9055                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9056                    + ", uid=" + callingUid + ") that is not exported from uid "
9057                    + cpi.applicationInfo.uid;
9058        } else {
9059            msg = "Permission Denial: opening provider " + cpi.name
9060                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9061                    + ", uid=" + callingUid + ") requires "
9062                    + cpi.readPermission + " or " + cpi.writePermission;
9063        }
9064        Slog.w(TAG, msg);
9065        return msg;
9066    }
9067
9068    /**
9069     * Returns if the ContentProvider has granted a uri to callingUid
9070     */
9071    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9072        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9073        if (perms != null) {
9074            for (int i=perms.size()-1; i>=0; i--) {
9075                GrantUri grantUri = perms.keyAt(i);
9076                if (grantUri.sourceUserId == userId || !checkUser) {
9077                    if (matchesProvider(grantUri.uri, cpi)) {
9078                        return true;
9079                    }
9080                }
9081            }
9082        }
9083        return false;
9084    }
9085
9086    /**
9087     * Returns true if the uri authority is one of the authorities specified in the provider.
9088     */
9089    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9090        String uriAuth = uri.getAuthority();
9091        String cpiAuth = cpi.authority;
9092        if (cpiAuth.indexOf(';') == -1) {
9093            return cpiAuth.equals(uriAuth);
9094        }
9095        String[] cpiAuths = cpiAuth.split(";");
9096        int length = cpiAuths.length;
9097        for (int i = 0; i < length; i++) {
9098            if (cpiAuths[i].equals(uriAuth)) return true;
9099        }
9100        return false;
9101    }
9102
9103    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9104            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9105        if (r != null) {
9106            for (int i=0; i<r.conProviders.size(); i++) {
9107                ContentProviderConnection conn = r.conProviders.get(i);
9108                if (conn.provider == cpr) {
9109                    if (DEBUG_PROVIDER) Slog.v(TAG,
9110                            "Adding provider requested by "
9111                            + r.processName + " from process "
9112                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9113                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9114                    if (stable) {
9115                        conn.stableCount++;
9116                        conn.numStableIncs++;
9117                    } else {
9118                        conn.unstableCount++;
9119                        conn.numUnstableIncs++;
9120                    }
9121                    return conn;
9122                }
9123            }
9124            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9125            if (stable) {
9126                conn.stableCount = 1;
9127                conn.numStableIncs = 1;
9128            } else {
9129                conn.unstableCount = 1;
9130                conn.numUnstableIncs = 1;
9131            }
9132            cpr.connections.add(conn);
9133            r.conProviders.add(conn);
9134            return conn;
9135        }
9136        cpr.addExternalProcessHandleLocked(externalProcessToken);
9137        return null;
9138    }
9139
9140    boolean decProviderCountLocked(ContentProviderConnection conn,
9141            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9142        if (conn != null) {
9143            cpr = conn.provider;
9144            if (DEBUG_PROVIDER) Slog.v(TAG,
9145                    "Removing provider requested by "
9146                    + conn.client.processName + " from process "
9147                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9148                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9149            if (stable) {
9150                conn.stableCount--;
9151            } else {
9152                conn.unstableCount--;
9153            }
9154            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9155                cpr.connections.remove(conn);
9156                conn.client.conProviders.remove(conn);
9157                return true;
9158            }
9159            return false;
9160        }
9161        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9162        return false;
9163    }
9164
9165    private void checkTime(long startTime, String where) {
9166        long now = SystemClock.elapsedRealtime();
9167        if ((now-startTime) > 1000) {
9168            // If we are taking more than a second, log about it.
9169            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9170        }
9171    }
9172
9173    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9174            String name, IBinder token, boolean stable, int userId) {
9175        ContentProviderRecord cpr;
9176        ContentProviderConnection conn = null;
9177        ProviderInfo cpi = null;
9178
9179        synchronized(this) {
9180            long startTime = SystemClock.elapsedRealtime();
9181
9182            ProcessRecord r = null;
9183            if (caller != null) {
9184                r = getRecordForAppLocked(caller);
9185                if (r == null) {
9186                    throw new SecurityException(
9187                            "Unable to find app for caller " + caller
9188                          + " (pid=" + Binder.getCallingPid()
9189                          + ") when getting content provider " + name);
9190                }
9191            }
9192
9193            boolean checkCrossUser = true;
9194
9195            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9196
9197            // First check if this content provider has been published...
9198            cpr = mProviderMap.getProviderByName(name, userId);
9199            // If that didn't work, check if it exists for user 0 and then
9200            // verify that it's a singleton provider before using it.
9201            if (cpr == null && userId != UserHandle.USER_OWNER) {
9202                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9203                if (cpr != null) {
9204                    cpi = cpr.info;
9205                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9206                            cpi.name, cpi.flags)
9207                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9208                        userId = UserHandle.USER_OWNER;
9209                        checkCrossUser = false;
9210                    } else {
9211                        cpr = null;
9212                        cpi = null;
9213                    }
9214                }
9215            }
9216
9217            boolean providerRunning = cpr != null;
9218            if (providerRunning) {
9219                cpi = cpr.info;
9220                String msg;
9221                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9222                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9223                        != null) {
9224                    throw new SecurityException(msg);
9225                }
9226                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9227
9228                if (r != null && cpr.canRunHere(r)) {
9229                    // This provider has been published or is in the process
9230                    // of being published...  but it is also allowed to run
9231                    // in the caller's process, so don't make a connection
9232                    // and just let the caller instantiate its own instance.
9233                    ContentProviderHolder holder = cpr.newHolder(null);
9234                    // don't give caller the provider object, it needs
9235                    // to make its own.
9236                    holder.provider = null;
9237                    return holder;
9238                }
9239
9240                final long origId = Binder.clearCallingIdentity();
9241
9242                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9243
9244                // In this case the provider instance already exists, so we can
9245                // return it right away.
9246                conn = incProviderCountLocked(r, cpr, token, stable);
9247                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9248                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9249                        // If this is a perceptible app accessing the provider,
9250                        // make sure to count it as being accessed and thus
9251                        // back up on the LRU list.  This is good because
9252                        // content providers are often expensive to start.
9253                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9254                        updateLruProcessLocked(cpr.proc, false, null);
9255                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9256                    }
9257                }
9258
9259                if (cpr.proc != null) {
9260                    if (false) {
9261                        if (cpr.name.flattenToShortString().equals(
9262                                "com.android.providers.calendar/.CalendarProvider2")) {
9263                            Slog.v(TAG, "****************** KILLING "
9264                                + cpr.name.flattenToShortString());
9265                            Process.killProcess(cpr.proc.pid);
9266                        }
9267                    }
9268                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9269                    boolean success = updateOomAdjLocked(cpr.proc);
9270                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9271                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9272                    // NOTE: there is still a race here where a signal could be
9273                    // pending on the process even though we managed to update its
9274                    // adj level.  Not sure what to do about this, but at least
9275                    // the race is now smaller.
9276                    if (!success) {
9277                        // Uh oh...  it looks like the provider's process
9278                        // has been killed on us.  We need to wait for a new
9279                        // process to be started, and make sure its death
9280                        // doesn't kill our process.
9281                        Slog.i(TAG,
9282                                "Existing provider " + cpr.name.flattenToShortString()
9283                                + " is crashing; detaching " + r);
9284                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9285                        checkTime(startTime, "getContentProviderImpl: before appDied");
9286                        appDiedLocked(cpr.proc);
9287                        checkTime(startTime, "getContentProviderImpl: after appDied");
9288                        if (!lastRef) {
9289                            // This wasn't the last ref our process had on
9290                            // the provider...  we have now been killed, bail.
9291                            return null;
9292                        }
9293                        providerRunning = false;
9294                        conn = null;
9295                    }
9296                }
9297
9298                Binder.restoreCallingIdentity(origId);
9299            }
9300
9301            boolean singleton;
9302            if (!providerRunning) {
9303                try {
9304                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9305                    cpi = AppGlobals.getPackageManager().
9306                        resolveContentProvider(name,
9307                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9308                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9309                } catch (RemoteException ex) {
9310                }
9311                if (cpi == null) {
9312                    return null;
9313                }
9314                // If the provider is a singleton AND
9315                // (it's a call within the same user || the provider is a
9316                // privileged app)
9317                // Then allow connecting to the singleton provider
9318                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9319                        cpi.name, cpi.flags)
9320                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9321                if (singleton) {
9322                    userId = UserHandle.USER_OWNER;
9323                }
9324                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9325                checkTime(startTime, "getContentProviderImpl: got app info for user");
9326
9327                String msg;
9328                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9329                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9330                        != null) {
9331                    throw new SecurityException(msg);
9332                }
9333                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9334
9335                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9336                        && !cpi.processName.equals("system")) {
9337                    // If this content provider does not run in the system
9338                    // process, and the system is not yet ready to run other
9339                    // processes, then fail fast instead of hanging.
9340                    throw new IllegalArgumentException(
9341                            "Attempt to launch content provider before system ready");
9342                }
9343
9344                // Make sure that the user who owns this provider is started.  If not,
9345                // we don't want to allow it to run.
9346                if (mStartedUsers.get(userId) == null) {
9347                    Slog.w(TAG, "Unable to launch app "
9348                            + cpi.applicationInfo.packageName + "/"
9349                            + cpi.applicationInfo.uid + " for provider "
9350                            + name + ": user " + userId + " is stopped");
9351                    return null;
9352                }
9353
9354                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9355                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9356                cpr = mProviderMap.getProviderByClass(comp, userId);
9357                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9358                final boolean firstClass = cpr == null;
9359                if (firstClass) {
9360                    final long ident = Binder.clearCallingIdentity();
9361                    try {
9362                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9363                        ApplicationInfo ai =
9364                            AppGlobals.getPackageManager().
9365                                getApplicationInfo(
9366                                        cpi.applicationInfo.packageName,
9367                                        STOCK_PM_FLAGS, userId);
9368                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9369                        if (ai == null) {
9370                            Slog.w(TAG, "No package info for content provider "
9371                                    + cpi.name);
9372                            return null;
9373                        }
9374                        ai = getAppInfoForUser(ai, userId);
9375                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9376                    } catch (RemoteException ex) {
9377                        // pm is in same process, this will never happen.
9378                    } finally {
9379                        Binder.restoreCallingIdentity(ident);
9380                    }
9381                }
9382
9383                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9384
9385                if (r != null && cpr.canRunHere(r)) {
9386                    // If this is a multiprocess provider, then just return its
9387                    // info and allow the caller to instantiate it.  Only do
9388                    // this if the provider is the same user as the caller's
9389                    // process, or can run as root (so can be in any process).
9390                    return cpr.newHolder(null);
9391                }
9392
9393                if (DEBUG_PROVIDER) {
9394                    RuntimeException e = new RuntimeException("here");
9395                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9396                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9397                }
9398
9399                // This is single process, and our app is now connecting to it.
9400                // See if we are already in the process of launching this
9401                // provider.
9402                final int N = mLaunchingProviders.size();
9403                int i;
9404                for (i=0; i<N; i++) {
9405                    if (mLaunchingProviders.get(i) == cpr) {
9406                        break;
9407                    }
9408                }
9409
9410                // If the provider is not already being launched, then get it
9411                // started.
9412                if (i >= N) {
9413                    final long origId = Binder.clearCallingIdentity();
9414
9415                    try {
9416                        // Content provider is now in use, its package can't be stopped.
9417                        try {
9418                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9419                            AppGlobals.getPackageManager().setPackageStoppedState(
9420                                    cpr.appInfo.packageName, false, userId);
9421                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9422                        } catch (RemoteException e) {
9423                        } catch (IllegalArgumentException e) {
9424                            Slog.w(TAG, "Failed trying to unstop package "
9425                                    + cpr.appInfo.packageName + ": " + e);
9426                        }
9427
9428                        // Use existing process if already started
9429                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9430                        ProcessRecord proc = getProcessRecordLocked(
9431                                cpi.processName, cpr.appInfo.uid, false);
9432                        if (proc != null && proc.thread != null) {
9433                            if (DEBUG_PROVIDER) {
9434                                Slog.d(TAG, "Installing in existing process " + proc);
9435                            }
9436                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9437                            proc.pubProviders.put(cpi.name, cpr);
9438                            try {
9439                                proc.thread.scheduleInstallProvider(cpi);
9440                            } catch (RemoteException e) {
9441                            }
9442                        } else {
9443                            checkTime(startTime, "getContentProviderImpl: before start process");
9444                            proc = startProcessLocked(cpi.processName,
9445                                    cpr.appInfo, false, 0, "content provider",
9446                                    new ComponentName(cpi.applicationInfo.packageName,
9447                                            cpi.name), false, false, false);
9448                            checkTime(startTime, "getContentProviderImpl: after start process");
9449                            if (proc == null) {
9450                                Slog.w(TAG, "Unable to launch app "
9451                                        + cpi.applicationInfo.packageName + "/"
9452                                        + cpi.applicationInfo.uid + " for provider "
9453                                        + name + ": process is bad");
9454                                return null;
9455                            }
9456                        }
9457                        cpr.launchingApp = proc;
9458                        mLaunchingProviders.add(cpr);
9459                    } finally {
9460                        Binder.restoreCallingIdentity(origId);
9461                    }
9462                }
9463
9464                checkTime(startTime, "getContentProviderImpl: updating data structures");
9465
9466                // Make sure the provider is published (the same provider class
9467                // may be published under multiple names).
9468                if (firstClass) {
9469                    mProviderMap.putProviderByClass(comp, cpr);
9470                }
9471
9472                mProviderMap.putProviderByName(name, cpr);
9473                conn = incProviderCountLocked(r, cpr, token, stable);
9474                if (conn != null) {
9475                    conn.waiting = true;
9476                }
9477            }
9478            checkTime(startTime, "getContentProviderImpl: done!");
9479        }
9480
9481        // Wait for the provider to be published...
9482        synchronized (cpr) {
9483            while (cpr.provider == null) {
9484                if (cpr.launchingApp == null) {
9485                    Slog.w(TAG, "Unable to launch app "
9486                            + cpi.applicationInfo.packageName + "/"
9487                            + cpi.applicationInfo.uid + " for provider "
9488                            + name + ": launching app became null");
9489                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9490                            UserHandle.getUserId(cpi.applicationInfo.uid),
9491                            cpi.applicationInfo.packageName,
9492                            cpi.applicationInfo.uid, name);
9493                    return null;
9494                }
9495                try {
9496                    if (DEBUG_MU) {
9497                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9498                                + cpr.launchingApp);
9499                    }
9500                    if (conn != null) {
9501                        conn.waiting = true;
9502                    }
9503                    cpr.wait();
9504                } catch (InterruptedException ex) {
9505                } finally {
9506                    if (conn != null) {
9507                        conn.waiting = false;
9508                    }
9509                }
9510            }
9511        }
9512        return cpr != null ? cpr.newHolder(conn) : null;
9513    }
9514
9515    @Override
9516    public final ContentProviderHolder getContentProvider(
9517            IApplicationThread caller, String name, int userId, boolean stable) {
9518        enforceNotIsolatedCaller("getContentProvider");
9519        if (caller == null) {
9520            String msg = "null IApplicationThread when getting content provider "
9521                    + name;
9522            Slog.w(TAG, msg);
9523            throw new SecurityException(msg);
9524        }
9525        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9526        // with cross-user grant.
9527        return getContentProviderImpl(caller, name, null, stable, userId);
9528    }
9529
9530    public ContentProviderHolder getContentProviderExternal(
9531            String name, int userId, IBinder token) {
9532        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9533            "Do not have permission in call getContentProviderExternal()");
9534        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9535                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9536        return getContentProviderExternalUnchecked(name, token, userId);
9537    }
9538
9539    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9540            IBinder token, int userId) {
9541        return getContentProviderImpl(null, name, token, true, userId);
9542    }
9543
9544    /**
9545     * Drop a content provider from a ProcessRecord's bookkeeping
9546     */
9547    public void removeContentProvider(IBinder connection, boolean stable) {
9548        enforceNotIsolatedCaller("removeContentProvider");
9549        long ident = Binder.clearCallingIdentity();
9550        try {
9551            synchronized (this) {
9552                ContentProviderConnection conn;
9553                try {
9554                    conn = (ContentProviderConnection)connection;
9555                } catch (ClassCastException e) {
9556                    String msg ="removeContentProvider: " + connection
9557                            + " not a ContentProviderConnection";
9558                    Slog.w(TAG, msg);
9559                    throw new IllegalArgumentException(msg);
9560                }
9561                if (conn == null) {
9562                    throw new NullPointerException("connection is null");
9563                }
9564                if (decProviderCountLocked(conn, null, null, stable)) {
9565                    updateOomAdjLocked();
9566                }
9567            }
9568        } finally {
9569            Binder.restoreCallingIdentity(ident);
9570        }
9571    }
9572
9573    public void removeContentProviderExternal(String name, IBinder token) {
9574        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9575            "Do not have permission in call removeContentProviderExternal()");
9576        int userId = UserHandle.getCallingUserId();
9577        long ident = Binder.clearCallingIdentity();
9578        try {
9579            removeContentProviderExternalUnchecked(name, token, userId);
9580        } finally {
9581            Binder.restoreCallingIdentity(ident);
9582        }
9583    }
9584
9585    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9586        synchronized (this) {
9587            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9588            if(cpr == null) {
9589                //remove from mProvidersByClass
9590                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9591                return;
9592            }
9593
9594            //update content provider record entry info
9595            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9596            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9597            if (localCpr.hasExternalProcessHandles()) {
9598                if (localCpr.removeExternalProcessHandleLocked(token)) {
9599                    updateOomAdjLocked();
9600                } else {
9601                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9602                            + " with no external reference for token: "
9603                            + token + ".");
9604                }
9605            } else {
9606                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9607                        + " with no external references.");
9608            }
9609        }
9610    }
9611
9612    public final void publishContentProviders(IApplicationThread caller,
9613            List<ContentProviderHolder> providers) {
9614        if (providers == null) {
9615            return;
9616        }
9617
9618        enforceNotIsolatedCaller("publishContentProviders");
9619        synchronized (this) {
9620            final ProcessRecord r = getRecordForAppLocked(caller);
9621            if (DEBUG_MU)
9622                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9623            if (r == null) {
9624                throw new SecurityException(
9625                        "Unable to find app for caller " + caller
9626                      + " (pid=" + Binder.getCallingPid()
9627                      + ") when publishing content providers");
9628            }
9629
9630            final long origId = Binder.clearCallingIdentity();
9631
9632            final int N = providers.size();
9633            for (int i=0; i<N; i++) {
9634                ContentProviderHolder src = providers.get(i);
9635                if (src == null || src.info == null || src.provider == null) {
9636                    continue;
9637                }
9638                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9639                if (DEBUG_MU)
9640                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9641                if (dst != null) {
9642                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9643                    mProviderMap.putProviderByClass(comp, dst);
9644                    String names[] = dst.info.authority.split(";");
9645                    for (int j = 0; j < names.length; j++) {
9646                        mProviderMap.putProviderByName(names[j], dst);
9647                    }
9648
9649                    int NL = mLaunchingProviders.size();
9650                    int j;
9651                    for (j=0; j<NL; j++) {
9652                        if (mLaunchingProviders.get(j) == dst) {
9653                            mLaunchingProviders.remove(j);
9654                            j--;
9655                            NL--;
9656                        }
9657                    }
9658                    synchronized (dst) {
9659                        dst.provider = src.provider;
9660                        dst.proc = r;
9661                        dst.notifyAll();
9662                    }
9663                    updateOomAdjLocked(r);
9664                }
9665            }
9666
9667            Binder.restoreCallingIdentity(origId);
9668        }
9669    }
9670
9671    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9672        ContentProviderConnection conn;
9673        try {
9674            conn = (ContentProviderConnection)connection;
9675        } catch (ClassCastException e) {
9676            String msg ="refContentProvider: " + connection
9677                    + " not a ContentProviderConnection";
9678            Slog.w(TAG, msg);
9679            throw new IllegalArgumentException(msg);
9680        }
9681        if (conn == null) {
9682            throw new NullPointerException("connection is null");
9683        }
9684
9685        synchronized (this) {
9686            if (stable > 0) {
9687                conn.numStableIncs += stable;
9688            }
9689            stable = conn.stableCount + stable;
9690            if (stable < 0) {
9691                throw new IllegalStateException("stableCount < 0: " + stable);
9692            }
9693
9694            if (unstable > 0) {
9695                conn.numUnstableIncs += unstable;
9696            }
9697            unstable = conn.unstableCount + unstable;
9698            if (unstable < 0) {
9699                throw new IllegalStateException("unstableCount < 0: " + unstable);
9700            }
9701
9702            if ((stable+unstable) <= 0) {
9703                throw new IllegalStateException("ref counts can't go to zero here: stable="
9704                        + stable + " unstable=" + unstable);
9705            }
9706            conn.stableCount = stable;
9707            conn.unstableCount = unstable;
9708            return !conn.dead;
9709        }
9710    }
9711
9712    public void unstableProviderDied(IBinder connection) {
9713        ContentProviderConnection conn;
9714        try {
9715            conn = (ContentProviderConnection)connection;
9716        } catch (ClassCastException e) {
9717            String msg ="refContentProvider: " + connection
9718                    + " not a ContentProviderConnection";
9719            Slog.w(TAG, msg);
9720            throw new IllegalArgumentException(msg);
9721        }
9722        if (conn == null) {
9723            throw new NullPointerException("connection is null");
9724        }
9725
9726        // Safely retrieve the content provider associated with the connection.
9727        IContentProvider provider;
9728        synchronized (this) {
9729            provider = conn.provider.provider;
9730        }
9731
9732        if (provider == null) {
9733            // Um, yeah, we're way ahead of you.
9734            return;
9735        }
9736
9737        // Make sure the caller is being honest with us.
9738        if (provider.asBinder().pingBinder()) {
9739            // Er, no, still looks good to us.
9740            synchronized (this) {
9741                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9742                        + " says " + conn + " died, but we don't agree");
9743                return;
9744            }
9745        }
9746
9747        // Well look at that!  It's dead!
9748        synchronized (this) {
9749            if (conn.provider.provider != provider) {
9750                // But something changed...  good enough.
9751                return;
9752            }
9753
9754            ProcessRecord proc = conn.provider.proc;
9755            if (proc == null || proc.thread == null) {
9756                // Seems like the process is already cleaned up.
9757                return;
9758            }
9759
9760            // As far as we're concerned, this is just like receiving a
9761            // death notification...  just a bit prematurely.
9762            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9763                    + ") early provider death");
9764            final long ident = Binder.clearCallingIdentity();
9765            try {
9766                appDiedLocked(proc);
9767            } finally {
9768                Binder.restoreCallingIdentity(ident);
9769            }
9770        }
9771    }
9772
9773    @Override
9774    public void appNotRespondingViaProvider(IBinder connection) {
9775        enforceCallingPermission(
9776                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9777
9778        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9779        if (conn == null) {
9780            Slog.w(TAG, "ContentProviderConnection is null");
9781            return;
9782        }
9783
9784        final ProcessRecord host = conn.provider.proc;
9785        if (host == null) {
9786            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9787            return;
9788        }
9789
9790        final long token = Binder.clearCallingIdentity();
9791        try {
9792            appNotResponding(host, null, null, false, "ContentProvider not responding");
9793        } finally {
9794            Binder.restoreCallingIdentity(token);
9795        }
9796    }
9797
9798    public final void installSystemProviders() {
9799        List<ProviderInfo> providers;
9800        synchronized (this) {
9801            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9802            providers = generateApplicationProvidersLocked(app);
9803            if (providers != null) {
9804                for (int i=providers.size()-1; i>=0; i--) {
9805                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9806                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9807                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9808                                + ": not system .apk");
9809                        providers.remove(i);
9810                    }
9811                }
9812            }
9813        }
9814        if (providers != null) {
9815            mSystemThread.installSystemProviders(providers);
9816        }
9817
9818        mCoreSettingsObserver = new CoreSettingsObserver(this);
9819
9820        //mUsageStatsService.monitorPackages();
9821    }
9822
9823    /**
9824     * Allows apps to retrieve the MIME type of a URI.
9825     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9826     * users, then it does not need permission to access the ContentProvider.
9827     * Either, it needs cross-user uri grants.
9828     *
9829     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9830     *
9831     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9832     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9833     */
9834    public String getProviderMimeType(Uri uri, int userId) {
9835        enforceNotIsolatedCaller("getProviderMimeType");
9836        final String name = uri.getAuthority();
9837        int callingUid = Binder.getCallingUid();
9838        int callingPid = Binder.getCallingPid();
9839        long ident = 0;
9840        boolean clearedIdentity = false;
9841        userId = unsafeConvertIncomingUser(userId);
9842        if (canClearIdentity(callingPid, callingUid, userId)) {
9843            clearedIdentity = true;
9844            ident = Binder.clearCallingIdentity();
9845        }
9846        ContentProviderHolder holder = null;
9847        try {
9848            holder = getContentProviderExternalUnchecked(name, null, userId);
9849            if (holder != null) {
9850                return holder.provider.getType(uri);
9851            }
9852        } catch (RemoteException e) {
9853            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9854            return null;
9855        } finally {
9856            // We need to clear the identity to call removeContentProviderExternalUnchecked
9857            if (!clearedIdentity) {
9858                ident = Binder.clearCallingIdentity();
9859            }
9860            try {
9861                if (holder != null) {
9862                    removeContentProviderExternalUnchecked(name, null, userId);
9863                }
9864            } finally {
9865                Binder.restoreCallingIdentity(ident);
9866            }
9867        }
9868
9869        return null;
9870    }
9871
9872    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9873        if (UserHandle.getUserId(callingUid) == userId) {
9874            return true;
9875        }
9876        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9877                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9878                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9879                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9880                return true;
9881        }
9882        return false;
9883    }
9884
9885    // =========================================================
9886    // GLOBAL MANAGEMENT
9887    // =========================================================
9888
9889    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9890            boolean isolated, int isolatedUid) {
9891        String proc = customProcess != null ? customProcess : info.processName;
9892        BatteryStatsImpl.Uid.Proc ps = null;
9893        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9894        int uid = info.uid;
9895        if (isolated) {
9896            if (isolatedUid == 0) {
9897                int userId = UserHandle.getUserId(uid);
9898                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9899                while (true) {
9900                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9901                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9902                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9903                    }
9904                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9905                    mNextIsolatedProcessUid++;
9906                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9907                        // No process for this uid, use it.
9908                        break;
9909                    }
9910                    stepsLeft--;
9911                    if (stepsLeft <= 0) {
9912                        return null;
9913                    }
9914                }
9915            } else {
9916                // Special case for startIsolatedProcess (internal only), where
9917                // the uid of the isolated process is specified by the caller.
9918                uid = isolatedUid;
9919            }
9920        }
9921        return new ProcessRecord(stats, info, proc, uid);
9922    }
9923
9924    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9925            String abiOverride) {
9926        ProcessRecord app;
9927        if (!isolated) {
9928            app = getProcessRecordLocked(info.processName, info.uid, true);
9929        } else {
9930            app = null;
9931        }
9932
9933        if (app == null) {
9934            app = newProcessRecordLocked(info, null, isolated, 0);
9935            mProcessNames.put(info.processName, app.uid, app);
9936            if (isolated) {
9937                mIsolatedProcesses.put(app.uid, app);
9938            }
9939            updateLruProcessLocked(app, false, null);
9940            updateOomAdjLocked();
9941        }
9942
9943        // This package really, really can not be stopped.
9944        try {
9945            AppGlobals.getPackageManager().setPackageStoppedState(
9946                    info.packageName, false, UserHandle.getUserId(app.uid));
9947        } catch (RemoteException e) {
9948        } catch (IllegalArgumentException e) {
9949            Slog.w(TAG, "Failed trying to unstop package "
9950                    + info.packageName + ": " + e);
9951        }
9952
9953        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9954                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9955            app.persistent = true;
9956            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9957        }
9958        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9959            mPersistentStartingProcesses.add(app);
9960            startProcessLocked(app, "added application", app.processName, abiOverride,
9961                    null /* entryPoint */, null /* entryPointArgs */);
9962        }
9963
9964        return app;
9965    }
9966
9967    public void unhandledBack() {
9968        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9969                "unhandledBack()");
9970
9971        synchronized(this) {
9972            final long origId = Binder.clearCallingIdentity();
9973            try {
9974                getFocusedStack().unhandledBackLocked();
9975            } finally {
9976                Binder.restoreCallingIdentity(origId);
9977            }
9978        }
9979    }
9980
9981    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9982        enforceNotIsolatedCaller("openContentUri");
9983        final int userId = UserHandle.getCallingUserId();
9984        String name = uri.getAuthority();
9985        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9986        ParcelFileDescriptor pfd = null;
9987        if (cph != null) {
9988            // We record the binder invoker's uid in thread-local storage before
9989            // going to the content provider to open the file.  Later, in the code
9990            // that handles all permissions checks, we look for this uid and use
9991            // that rather than the Activity Manager's own uid.  The effect is that
9992            // we do the check against the caller's permissions even though it looks
9993            // to the content provider like the Activity Manager itself is making
9994            // the request.
9995            sCallerIdentity.set(new Identity(
9996                    Binder.getCallingPid(), Binder.getCallingUid()));
9997            try {
9998                pfd = cph.provider.openFile(null, uri, "r", null);
9999            } catch (FileNotFoundException e) {
10000                // do nothing; pfd will be returned null
10001            } finally {
10002                // Ensure that whatever happens, we clean up the identity state
10003                sCallerIdentity.remove();
10004            }
10005
10006            // We've got the fd now, so we're done with the provider.
10007            removeContentProviderExternalUnchecked(name, null, userId);
10008        } else {
10009            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10010        }
10011        return pfd;
10012    }
10013
10014    // Actually is sleeping or shutting down or whatever else in the future
10015    // is an inactive state.
10016    public boolean isSleepingOrShuttingDown() {
10017        return isSleeping() || mShuttingDown;
10018    }
10019
10020    public boolean isSleeping() {
10021        return mSleeping;
10022    }
10023
10024    void goingToSleep() {
10025        synchronized(this) {
10026            mWentToSleep = true;
10027            goToSleepIfNeededLocked();
10028        }
10029    }
10030
10031    void finishRunningVoiceLocked() {
10032        if (mRunningVoice) {
10033            mRunningVoice = false;
10034            goToSleepIfNeededLocked();
10035        }
10036    }
10037
10038    void goToSleepIfNeededLocked() {
10039        if (mWentToSleep && !mRunningVoice) {
10040            if (!mSleeping) {
10041                mSleeping = true;
10042                mStackSupervisor.goingToSleepLocked();
10043
10044                // Initialize the wake times of all processes.
10045                checkExcessivePowerUsageLocked(false);
10046                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10047                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10048                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10049            }
10050        }
10051    }
10052
10053    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10054        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10055            // Never persist the home stack.
10056            return;
10057        }
10058        mTaskPersister.wakeup(task, flush);
10059    }
10060
10061    @Override
10062    public boolean shutdown(int timeout) {
10063        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10064                != PackageManager.PERMISSION_GRANTED) {
10065            throw new SecurityException("Requires permission "
10066                    + android.Manifest.permission.SHUTDOWN);
10067        }
10068
10069        boolean timedout = false;
10070
10071        synchronized(this) {
10072            mShuttingDown = true;
10073            updateEventDispatchingLocked();
10074            timedout = mStackSupervisor.shutdownLocked(timeout);
10075        }
10076
10077        mAppOpsService.shutdown();
10078        if (mUsageStatsService != null) {
10079            mUsageStatsService.prepareShutdown();
10080        }
10081        mBatteryStatsService.shutdown();
10082        synchronized (this) {
10083            mProcessStats.shutdownLocked();
10084        }
10085        notifyTaskPersisterLocked(null, true);
10086
10087        return timedout;
10088    }
10089
10090    public final void activitySlept(IBinder token) {
10091        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10092
10093        final long origId = Binder.clearCallingIdentity();
10094
10095        synchronized (this) {
10096            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10097            if (r != null) {
10098                mStackSupervisor.activitySleptLocked(r);
10099            }
10100        }
10101
10102        Binder.restoreCallingIdentity(origId);
10103    }
10104
10105    void logLockScreen(String msg) {
10106        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10107                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10108                mWentToSleep + " mSleeping=" + mSleeping);
10109    }
10110
10111    private void comeOutOfSleepIfNeededLocked() {
10112        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10113            if (mSleeping) {
10114                mSleeping = false;
10115                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10116            }
10117        }
10118    }
10119
10120    void wakingUp() {
10121        synchronized(this) {
10122            mWentToSleep = false;
10123            comeOutOfSleepIfNeededLocked();
10124        }
10125    }
10126
10127    void startRunningVoiceLocked() {
10128        if (!mRunningVoice) {
10129            mRunningVoice = true;
10130            comeOutOfSleepIfNeededLocked();
10131        }
10132    }
10133
10134    private void updateEventDispatchingLocked() {
10135        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10136    }
10137
10138    public void setLockScreenShown(boolean shown) {
10139        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10140                != PackageManager.PERMISSION_GRANTED) {
10141            throw new SecurityException("Requires permission "
10142                    + android.Manifest.permission.DEVICE_POWER);
10143        }
10144
10145        synchronized(this) {
10146            long ident = Binder.clearCallingIdentity();
10147            try {
10148                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10149                mLockScreenShown = shown;
10150                comeOutOfSleepIfNeededLocked();
10151            } finally {
10152                Binder.restoreCallingIdentity(ident);
10153            }
10154        }
10155    }
10156
10157    @Override
10158    public void stopAppSwitches() {
10159        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10160                != PackageManager.PERMISSION_GRANTED) {
10161            throw new SecurityException("Requires permission "
10162                    + android.Manifest.permission.STOP_APP_SWITCHES);
10163        }
10164
10165        synchronized(this) {
10166            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10167                    + APP_SWITCH_DELAY_TIME;
10168            mDidAppSwitch = false;
10169            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10170            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10171            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10172        }
10173    }
10174
10175    public void resumeAppSwitches() {
10176        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10177                != PackageManager.PERMISSION_GRANTED) {
10178            throw new SecurityException("Requires permission "
10179                    + android.Manifest.permission.STOP_APP_SWITCHES);
10180        }
10181
10182        synchronized(this) {
10183            // Note that we don't execute any pending app switches... we will
10184            // let those wait until either the timeout, or the next start
10185            // activity request.
10186            mAppSwitchesAllowedTime = 0;
10187        }
10188    }
10189
10190    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10191            int callingPid, int callingUid, String name) {
10192        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10193            return true;
10194        }
10195
10196        int perm = checkComponentPermission(
10197                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10198                sourceUid, -1, true);
10199        if (perm == PackageManager.PERMISSION_GRANTED) {
10200            return true;
10201        }
10202
10203        // If the actual IPC caller is different from the logical source, then
10204        // also see if they are allowed to control app switches.
10205        if (callingUid != -1 && callingUid != sourceUid) {
10206            perm = checkComponentPermission(
10207                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10208                    callingUid, -1, true);
10209            if (perm == PackageManager.PERMISSION_GRANTED) {
10210                return true;
10211            }
10212        }
10213
10214        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10215        return false;
10216    }
10217
10218    public void setDebugApp(String packageName, boolean waitForDebugger,
10219            boolean persistent) {
10220        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10221                "setDebugApp()");
10222
10223        long ident = Binder.clearCallingIdentity();
10224        try {
10225            // Note that this is not really thread safe if there are multiple
10226            // callers into it at the same time, but that's not a situation we
10227            // care about.
10228            if (persistent) {
10229                final ContentResolver resolver = mContext.getContentResolver();
10230                Settings.Global.putString(
10231                    resolver, Settings.Global.DEBUG_APP,
10232                    packageName);
10233                Settings.Global.putInt(
10234                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10235                    waitForDebugger ? 1 : 0);
10236            }
10237
10238            synchronized (this) {
10239                if (!persistent) {
10240                    mOrigDebugApp = mDebugApp;
10241                    mOrigWaitForDebugger = mWaitForDebugger;
10242                }
10243                mDebugApp = packageName;
10244                mWaitForDebugger = waitForDebugger;
10245                mDebugTransient = !persistent;
10246                if (packageName != null) {
10247                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10248                            false, UserHandle.USER_ALL, "set debug app");
10249                }
10250            }
10251        } finally {
10252            Binder.restoreCallingIdentity(ident);
10253        }
10254    }
10255
10256    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10257        synchronized (this) {
10258            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10259            if (!isDebuggable) {
10260                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10261                    throw new SecurityException("Process not debuggable: " + app.packageName);
10262                }
10263            }
10264
10265            mOpenGlTraceApp = processName;
10266        }
10267    }
10268
10269    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10270        synchronized (this) {
10271            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10272            if (!isDebuggable) {
10273                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10274                    throw new SecurityException("Process not debuggable: " + app.packageName);
10275                }
10276            }
10277            mProfileApp = processName;
10278            mProfileFile = profilerInfo.profileFile;
10279            if (mProfileFd != null) {
10280                try {
10281                    mProfileFd.close();
10282                } catch (IOException e) {
10283                }
10284                mProfileFd = null;
10285            }
10286            mProfileFd = profilerInfo.profileFd;
10287            mSamplingInterval = profilerInfo.samplingInterval;
10288            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10289            mProfileType = 0;
10290        }
10291    }
10292
10293    @Override
10294    public void setAlwaysFinish(boolean enabled) {
10295        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10296                "setAlwaysFinish()");
10297
10298        Settings.Global.putInt(
10299                mContext.getContentResolver(),
10300                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10301
10302        synchronized (this) {
10303            mAlwaysFinishActivities = enabled;
10304        }
10305    }
10306
10307    @Override
10308    public void setActivityController(IActivityController controller) {
10309        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10310                "setActivityController()");
10311        synchronized (this) {
10312            mController = controller;
10313            Watchdog.getInstance().setActivityController(controller);
10314        }
10315    }
10316
10317    @Override
10318    public void setUserIsMonkey(boolean userIsMonkey) {
10319        synchronized (this) {
10320            synchronized (mPidsSelfLocked) {
10321                final int callingPid = Binder.getCallingPid();
10322                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10323                if (precessRecord == null) {
10324                    throw new SecurityException("Unknown process: " + callingPid);
10325                }
10326                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10327                    throw new SecurityException("Only an instrumentation process "
10328                            + "with a UiAutomation can call setUserIsMonkey");
10329                }
10330            }
10331            mUserIsMonkey = userIsMonkey;
10332        }
10333    }
10334
10335    @Override
10336    public boolean isUserAMonkey() {
10337        synchronized (this) {
10338            // If there is a controller also implies the user is a monkey.
10339            return (mUserIsMonkey || mController != null);
10340        }
10341    }
10342
10343    public void requestBugReport() {
10344        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10345        SystemProperties.set("ctl.start", "bugreport");
10346    }
10347
10348    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10349        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10350    }
10351
10352    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10353        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10354            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10355        }
10356        return KEY_DISPATCHING_TIMEOUT;
10357    }
10358
10359    @Override
10360    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10361        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10362                != PackageManager.PERMISSION_GRANTED) {
10363            throw new SecurityException("Requires permission "
10364                    + android.Manifest.permission.FILTER_EVENTS);
10365        }
10366        ProcessRecord proc;
10367        long timeout;
10368        synchronized (this) {
10369            synchronized (mPidsSelfLocked) {
10370                proc = mPidsSelfLocked.get(pid);
10371            }
10372            timeout = getInputDispatchingTimeoutLocked(proc);
10373        }
10374
10375        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10376            return -1;
10377        }
10378
10379        return timeout;
10380    }
10381
10382    /**
10383     * Handle input dispatching timeouts.
10384     * Returns whether input dispatching should be aborted or not.
10385     */
10386    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10387            final ActivityRecord activity, final ActivityRecord parent,
10388            final boolean aboveSystem, String reason) {
10389        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10390                != PackageManager.PERMISSION_GRANTED) {
10391            throw new SecurityException("Requires permission "
10392                    + android.Manifest.permission.FILTER_EVENTS);
10393        }
10394
10395        final String annotation;
10396        if (reason == null) {
10397            annotation = "Input dispatching timed out";
10398        } else {
10399            annotation = "Input dispatching timed out (" + reason + ")";
10400        }
10401
10402        if (proc != null) {
10403            synchronized (this) {
10404                if (proc.debugging) {
10405                    return false;
10406                }
10407
10408                if (mDidDexOpt) {
10409                    // Give more time since we were dexopting.
10410                    mDidDexOpt = false;
10411                    return false;
10412                }
10413
10414                if (proc.instrumentationClass != null) {
10415                    Bundle info = new Bundle();
10416                    info.putString("shortMsg", "keyDispatchingTimedOut");
10417                    info.putString("longMsg", annotation);
10418                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10419                    return true;
10420                }
10421            }
10422            mHandler.post(new Runnable() {
10423                @Override
10424                public void run() {
10425                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10426                }
10427            });
10428        }
10429
10430        return true;
10431    }
10432
10433    public Bundle getAssistContextExtras(int requestType) {
10434        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10435                "getAssistContextExtras()");
10436        PendingAssistExtras pae;
10437        Bundle extras = new Bundle();
10438        synchronized (this) {
10439            ActivityRecord activity = getFocusedStack().mResumedActivity;
10440            if (activity == null) {
10441                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10442                return null;
10443            }
10444            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10445            if (activity.app == null || activity.app.thread == null) {
10446                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10447                return extras;
10448            }
10449            if (activity.app.pid == Binder.getCallingPid()) {
10450                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10451                return extras;
10452            }
10453            pae = new PendingAssistExtras(activity);
10454            try {
10455                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10456                        requestType);
10457                mPendingAssistExtras.add(pae);
10458                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10459            } catch (RemoteException e) {
10460                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10461                return extras;
10462            }
10463        }
10464        synchronized (pae) {
10465            while (!pae.haveResult) {
10466                try {
10467                    pae.wait();
10468                } catch (InterruptedException e) {
10469                }
10470            }
10471            if (pae.result != null) {
10472                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10473            }
10474        }
10475        synchronized (this) {
10476            mPendingAssistExtras.remove(pae);
10477            mHandler.removeCallbacks(pae);
10478        }
10479        return extras;
10480    }
10481
10482    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10483        PendingAssistExtras pae = (PendingAssistExtras)token;
10484        synchronized (pae) {
10485            pae.result = extras;
10486            pae.haveResult = true;
10487            pae.notifyAll();
10488        }
10489    }
10490
10491    public void registerProcessObserver(IProcessObserver observer) {
10492        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10493                "registerProcessObserver()");
10494        synchronized (this) {
10495            mProcessObservers.register(observer);
10496        }
10497    }
10498
10499    @Override
10500    public void unregisterProcessObserver(IProcessObserver observer) {
10501        synchronized (this) {
10502            mProcessObservers.unregister(observer);
10503        }
10504    }
10505
10506    @Override
10507    public boolean convertFromTranslucent(IBinder token) {
10508        final long origId = Binder.clearCallingIdentity();
10509        try {
10510            synchronized (this) {
10511                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10512                if (r == null) {
10513                    return false;
10514                }
10515                final boolean translucentChanged = r.changeWindowTranslucency(true);
10516                if (translucentChanged) {
10517                    r.task.stack.releaseBackgroundResources();
10518                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10519                }
10520                mWindowManager.setAppFullscreen(token, true);
10521                return translucentChanged;
10522            }
10523        } finally {
10524            Binder.restoreCallingIdentity(origId);
10525        }
10526    }
10527
10528    @Override
10529    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10530        final long origId = Binder.clearCallingIdentity();
10531        try {
10532            synchronized (this) {
10533                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534                if (r == null) {
10535                    return false;
10536                }
10537                int index = r.task.mActivities.lastIndexOf(r);
10538                if (index > 0) {
10539                    ActivityRecord under = r.task.mActivities.get(index - 1);
10540                    under.returningOptions = options;
10541                }
10542                final boolean translucentChanged = r.changeWindowTranslucency(false);
10543                if (translucentChanged) {
10544                    r.task.stack.convertToTranslucent(r);
10545                }
10546                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10547                mWindowManager.setAppFullscreen(token, false);
10548                return translucentChanged;
10549            }
10550        } finally {
10551            Binder.restoreCallingIdentity(origId);
10552        }
10553    }
10554
10555    @Override
10556    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10557        final long origId = Binder.clearCallingIdentity();
10558        try {
10559            synchronized (this) {
10560                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10561                if (r != null) {
10562                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10563                }
10564            }
10565            return false;
10566        } finally {
10567            Binder.restoreCallingIdentity(origId);
10568        }
10569    }
10570
10571    @Override
10572    public boolean isBackgroundVisibleBehind(IBinder token) {
10573        final long origId = Binder.clearCallingIdentity();
10574        try {
10575            synchronized (this) {
10576                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10577                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10578                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10579                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10580                return visible;
10581            }
10582        } finally {
10583            Binder.restoreCallingIdentity(origId);
10584        }
10585    }
10586
10587    @Override
10588    public ActivityOptions getActivityOptions(IBinder token) {
10589        final long origId = Binder.clearCallingIdentity();
10590        try {
10591            synchronized (this) {
10592                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10593                if (r != null) {
10594                    final ActivityOptions activityOptions = r.pendingOptions;
10595                    r.pendingOptions = null;
10596                    return activityOptions;
10597                }
10598                return null;
10599            }
10600        } finally {
10601            Binder.restoreCallingIdentity(origId);
10602        }
10603    }
10604
10605    @Override
10606    public void setImmersive(IBinder token, boolean immersive) {
10607        synchronized(this) {
10608            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10609            if (r == null) {
10610                throw new IllegalArgumentException();
10611            }
10612            r.immersive = immersive;
10613
10614            // update associated state if we're frontmost
10615            if (r == mFocusedActivity) {
10616                if (DEBUG_IMMERSIVE) {
10617                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10618                }
10619                applyUpdateLockStateLocked(r);
10620            }
10621        }
10622    }
10623
10624    @Override
10625    public boolean isImmersive(IBinder token) {
10626        synchronized (this) {
10627            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10628            if (r == null) {
10629                throw new IllegalArgumentException();
10630            }
10631            return r.immersive;
10632        }
10633    }
10634
10635    public boolean isTopActivityImmersive() {
10636        enforceNotIsolatedCaller("startActivity");
10637        synchronized (this) {
10638            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10639            return (r != null) ? r.immersive : false;
10640        }
10641    }
10642
10643    @Override
10644    public boolean isTopOfTask(IBinder token) {
10645        synchronized (this) {
10646            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10647            if (r == null) {
10648                throw new IllegalArgumentException();
10649            }
10650            return r.task.getTopActivity() == r;
10651        }
10652    }
10653
10654    public final void enterSafeMode() {
10655        synchronized(this) {
10656            // It only makes sense to do this before the system is ready
10657            // and started launching other packages.
10658            if (!mSystemReady) {
10659                try {
10660                    AppGlobals.getPackageManager().enterSafeMode();
10661                } catch (RemoteException e) {
10662                }
10663            }
10664
10665            mSafeMode = true;
10666        }
10667    }
10668
10669    public final void showSafeModeOverlay() {
10670        View v = LayoutInflater.from(mContext).inflate(
10671                com.android.internal.R.layout.safe_mode, null);
10672        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10673        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10674        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10675        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10676        lp.gravity = Gravity.BOTTOM | Gravity.START;
10677        lp.format = v.getBackground().getOpacity();
10678        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10679                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10680        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10681        ((WindowManager)mContext.getSystemService(
10682                Context.WINDOW_SERVICE)).addView(v, lp);
10683    }
10684
10685    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10686        if (!(sender instanceof PendingIntentRecord)) {
10687            return;
10688        }
10689        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10690        synchronized (stats) {
10691            if (mBatteryStatsService.isOnBattery()) {
10692                mBatteryStatsService.enforceCallingPermission();
10693                PendingIntentRecord rec = (PendingIntentRecord)sender;
10694                int MY_UID = Binder.getCallingUid();
10695                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10696                BatteryStatsImpl.Uid.Pkg pkg =
10697                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10698                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10699                pkg.incWakeupsLocked();
10700            }
10701        }
10702    }
10703
10704    public boolean killPids(int[] pids, String pReason, boolean secure) {
10705        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10706            throw new SecurityException("killPids only available to the system");
10707        }
10708        String reason = (pReason == null) ? "Unknown" : pReason;
10709        // XXX Note: don't acquire main activity lock here, because the window
10710        // manager calls in with its locks held.
10711
10712        boolean killed = false;
10713        synchronized (mPidsSelfLocked) {
10714            int[] types = new int[pids.length];
10715            int worstType = 0;
10716            for (int i=0; i<pids.length; i++) {
10717                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10718                if (proc != null) {
10719                    int type = proc.setAdj;
10720                    types[i] = type;
10721                    if (type > worstType) {
10722                        worstType = type;
10723                    }
10724                }
10725            }
10726
10727            // If the worst oom_adj is somewhere in the cached proc LRU range,
10728            // then constrain it so we will kill all cached procs.
10729            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10730                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10731                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10732            }
10733
10734            // If this is not a secure call, don't let it kill processes that
10735            // are important.
10736            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10737                worstType = ProcessList.SERVICE_ADJ;
10738            }
10739
10740            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10741            for (int i=0; i<pids.length; i++) {
10742                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10743                if (proc == null) {
10744                    continue;
10745                }
10746                int adj = proc.setAdj;
10747                if (adj >= worstType && !proc.killedByAm) {
10748                    proc.kill(reason, true);
10749                    killed = true;
10750                }
10751            }
10752        }
10753        return killed;
10754    }
10755
10756    @Override
10757    public void killUid(int uid, String reason) {
10758        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10759            throw new SecurityException("killUid only available to the system");
10760        }
10761        synchronized (this) {
10762            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10763                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10764                    reason != null ? reason : "kill uid");
10765        }
10766    }
10767
10768    @Override
10769    public boolean killProcessesBelowForeground(String reason) {
10770        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10771            throw new SecurityException("killProcessesBelowForeground() only available to system");
10772        }
10773
10774        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10775    }
10776
10777    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10778        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10779            throw new SecurityException("killProcessesBelowAdj() only available to system");
10780        }
10781
10782        boolean killed = false;
10783        synchronized (mPidsSelfLocked) {
10784            final int size = mPidsSelfLocked.size();
10785            for (int i = 0; i < size; i++) {
10786                final int pid = mPidsSelfLocked.keyAt(i);
10787                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10788                if (proc == null) continue;
10789
10790                final int adj = proc.setAdj;
10791                if (adj > belowAdj && !proc.killedByAm) {
10792                    proc.kill(reason, true);
10793                    killed = true;
10794                }
10795            }
10796        }
10797        return killed;
10798    }
10799
10800    @Override
10801    public void hang(final IBinder who, boolean allowRestart) {
10802        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10803                != PackageManager.PERMISSION_GRANTED) {
10804            throw new SecurityException("Requires permission "
10805                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10806        }
10807
10808        final IBinder.DeathRecipient death = new DeathRecipient() {
10809            @Override
10810            public void binderDied() {
10811                synchronized (this) {
10812                    notifyAll();
10813                }
10814            }
10815        };
10816
10817        try {
10818            who.linkToDeath(death, 0);
10819        } catch (RemoteException e) {
10820            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10821            return;
10822        }
10823
10824        synchronized (this) {
10825            Watchdog.getInstance().setAllowRestart(allowRestart);
10826            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10827            synchronized (death) {
10828                while (who.isBinderAlive()) {
10829                    try {
10830                        death.wait();
10831                    } catch (InterruptedException e) {
10832                    }
10833                }
10834            }
10835            Watchdog.getInstance().setAllowRestart(true);
10836        }
10837    }
10838
10839    @Override
10840    public void restart() {
10841        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10842                != PackageManager.PERMISSION_GRANTED) {
10843            throw new SecurityException("Requires permission "
10844                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10845        }
10846
10847        Log.i(TAG, "Sending shutdown broadcast...");
10848
10849        BroadcastReceiver br = new BroadcastReceiver() {
10850            @Override public void onReceive(Context context, Intent intent) {
10851                // Now the broadcast is done, finish up the low-level shutdown.
10852                Log.i(TAG, "Shutting down activity manager...");
10853                shutdown(10000);
10854                Log.i(TAG, "Shutdown complete, restarting!");
10855                Process.killProcess(Process.myPid());
10856                System.exit(10);
10857            }
10858        };
10859
10860        // First send the high-level shut down broadcast.
10861        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10862        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10863        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10864        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10865        mContext.sendOrderedBroadcastAsUser(intent,
10866                UserHandle.ALL, null, br, mHandler, 0, null, null);
10867        */
10868        br.onReceive(mContext, intent);
10869    }
10870
10871    private long getLowRamTimeSinceIdle(long now) {
10872        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10873    }
10874
10875    @Override
10876    public void performIdleMaintenance() {
10877        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10878                != PackageManager.PERMISSION_GRANTED) {
10879            throw new SecurityException("Requires permission "
10880                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10881        }
10882
10883        synchronized (this) {
10884            final long now = SystemClock.uptimeMillis();
10885            final long timeSinceLastIdle = now - mLastIdleTime;
10886            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10887            mLastIdleTime = now;
10888            mLowRamTimeSinceLastIdle = 0;
10889            if (mLowRamStartTime != 0) {
10890                mLowRamStartTime = now;
10891            }
10892
10893            StringBuilder sb = new StringBuilder(128);
10894            sb.append("Idle maintenance over ");
10895            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10896            sb.append(" low RAM for ");
10897            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10898            Slog.i(TAG, sb.toString());
10899
10900            // If at least 1/3 of our time since the last idle period has been spent
10901            // with RAM low, then we want to kill processes.
10902            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10903
10904            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10905                ProcessRecord proc = mLruProcesses.get(i);
10906                if (proc.notCachedSinceIdle) {
10907                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10908                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10909                        if (doKilling && proc.initialIdlePss != 0
10910                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10911                            proc.kill("idle maint (pss " + proc.lastPss
10912                                    + " from " + proc.initialIdlePss + ")", true);
10913                        }
10914                    }
10915                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10916                    proc.notCachedSinceIdle = true;
10917                    proc.initialIdlePss = 0;
10918                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10919                            isSleeping(), now);
10920                }
10921            }
10922
10923            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10924            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10925        }
10926    }
10927
10928    private void retrieveSettings() {
10929        final ContentResolver resolver = mContext.getContentResolver();
10930        String debugApp = Settings.Global.getString(
10931            resolver, Settings.Global.DEBUG_APP);
10932        boolean waitForDebugger = Settings.Global.getInt(
10933            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10934        boolean alwaysFinishActivities = Settings.Global.getInt(
10935            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10936        boolean forceRtl = Settings.Global.getInt(
10937                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10938        // Transfer any global setting for forcing RTL layout, into a System Property
10939        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10940
10941        Configuration configuration = new Configuration();
10942        Settings.System.getConfiguration(resolver, configuration);
10943        if (forceRtl) {
10944            // This will take care of setting the correct layout direction flags
10945            configuration.setLayoutDirection(configuration.locale);
10946        }
10947
10948        synchronized (this) {
10949            mDebugApp = mOrigDebugApp = debugApp;
10950            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10951            mAlwaysFinishActivities = alwaysFinishActivities;
10952            // This happens before any activities are started, so we can
10953            // change mConfiguration in-place.
10954            updateConfigurationLocked(configuration, null, false, true);
10955            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10956        }
10957    }
10958
10959    /** Loads resources after the current configuration has been set. */
10960    private void loadResourcesOnSystemReady() {
10961        final Resources res = mContext.getResources();
10962        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10963        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10964        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10965    }
10966
10967    public boolean testIsSystemReady() {
10968        // no need to synchronize(this) just to read & return the value
10969        return mSystemReady;
10970    }
10971
10972    private static File getCalledPreBootReceiversFile() {
10973        File dataDir = Environment.getDataDirectory();
10974        File systemDir = new File(dataDir, "system");
10975        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10976        return fname;
10977    }
10978
10979    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10980        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10981        File file = getCalledPreBootReceiversFile();
10982        FileInputStream fis = null;
10983        try {
10984            fis = new FileInputStream(file);
10985            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10986            int fvers = dis.readInt();
10987            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10988                String vers = dis.readUTF();
10989                String codename = dis.readUTF();
10990                String build = dis.readUTF();
10991                if (android.os.Build.VERSION.RELEASE.equals(vers)
10992                        && android.os.Build.VERSION.CODENAME.equals(codename)
10993                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10994                    int num = dis.readInt();
10995                    while (num > 0) {
10996                        num--;
10997                        String pkg = dis.readUTF();
10998                        String cls = dis.readUTF();
10999                        lastDoneReceivers.add(new ComponentName(pkg, cls));
11000                    }
11001                }
11002            }
11003        } catch (FileNotFoundException e) {
11004        } catch (IOException e) {
11005            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11006        } finally {
11007            if (fis != null) {
11008                try {
11009                    fis.close();
11010                } catch (IOException e) {
11011                }
11012            }
11013        }
11014        return lastDoneReceivers;
11015    }
11016
11017    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11018        File file = getCalledPreBootReceiversFile();
11019        FileOutputStream fos = null;
11020        DataOutputStream dos = null;
11021        try {
11022            fos = new FileOutputStream(file);
11023            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11024            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11025            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11026            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11027            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11028            dos.writeInt(list.size());
11029            for (int i=0; i<list.size(); i++) {
11030                dos.writeUTF(list.get(i).getPackageName());
11031                dos.writeUTF(list.get(i).getClassName());
11032            }
11033        } catch (IOException e) {
11034            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11035            file.delete();
11036        } finally {
11037            FileUtils.sync(fos);
11038            if (dos != null) {
11039                try {
11040                    dos.close();
11041                } catch (IOException e) {
11042                    // TODO Auto-generated catch block
11043                    e.printStackTrace();
11044                }
11045            }
11046        }
11047    }
11048
11049    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11050            ArrayList<ComponentName> doneReceivers, int userId) {
11051        boolean waitingUpdate = false;
11052        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11053        List<ResolveInfo> ris = null;
11054        try {
11055            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11056                    intent, null, 0, userId);
11057        } catch (RemoteException e) {
11058        }
11059        if (ris != null) {
11060            for (int i=ris.size()-1; i>=0; i--) {
11061                if ((ris.get(i).activityInfo.applicationInfo.flags
11062                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11063                    ris.remove(i);
11064                }
11065            }
11066            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11067
11068            // For User 0, load the version number. When delivering to a new user, deliver
11069            // to all receivers.
11070            if (userId == UserHandle.USER_OWNER) {
11071                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11072                for (int i=0; i<ris.size(); i++) {
11073                    ActivityInfo ai = ris.get(i).activityInfo;
11074                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11075                    if (lastDoneReceivers.contains(comp)) {
11076                        // We already did the pre boot receiver for this app with the current
11077                        // platform version, so don't do it again...
11078                        ris.remove(i);
11079                        i--;
11080                        // ...however, do keep it as one that has been done, so we don't
11081                        // forget about it when rewriting the file of last done receivers.
11082                        doneReceivers.add(comp);
11083                    }
11084                }
11085            }
11086
11087            // If primary user, send broadcast to all available users, else just to userId
11088            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11089                    : new int[] { userId };
11090            for (int i = 0; i < ris.size(); i++) {
11091                ActivityInfo ai = ris.get(i).activityInfo;
11092                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11093                doneReceivers.add(comp);
11094                intent.setComponent(comp);
11095                for (int j=0; j<users.length; j++) {
11096                    IIntentReceiver finisher = null;
11097                    // On last receiver and user, set up a completion callback
11098                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11099                        finisher = new IIntentReceiver.Stub() {
11100                            public void performReceive(Intent intent, int resultCode,
11101                                    String data, Bundle extras, boolean ordered,
11102                                    boolean sticky, int sendingUser) {
11103                                // The raw IIntentReceiver interface is called
11104                                // with the AM lock held, so redispatch to
11105                                // execute our code without the lock.
11106                                mHandler.post(onFinishCallback);
11107                            }
11108                        };
11109                    }
11110                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11111                            + " for user " + users[j]);
11112                    broadcastIntentLocked(null, null, intent, null, finisher,
11113                            0, null, null, null, AppOpsManager.OP_NONE,
11114                            true, false, MY_PID, Process.SYSTEM_UID,
11115                            users[j]);
11116                    if (finisher != null) {
11117                        waitingUpdate = true;
11118                    }
11119                }
11120            }
11121        }
11122
11123        return waitingUpdate;
11124    }
11125
11126    public void systemReady(final Runnable goingCallback) {
11127        synchronized(this) {
11128            if (mSystemReady) {
11129                // If we're done calling all the receivers, run the next "boot phase" passed in
11130                // by the SystemServer
11131                if (goingCallback != null) {
11132                    goingCallback.run();
11133                }
11134                return;
11135            }
11136
11137            // Make sure we have the current profile info, since it is needed for
11138            // security checks.
11139            updateCurrentProfileIdsLocked();
11140
11141            if (mRecentTasks == null) {
11142                mRecentTasks = mTaskPersister.restoreTasksLocked();
11143                if (!mRecentTasks.isEmpty()) {
11144                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11145                }
11146                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11147                mTaskPersister.startPersisting();
11148            }
11149
11150            // Check to see if there are any update receivers to run.
11151            if (!mDidUpdate) {
11152                if (mWaitingUpdate) {
11153                    return;
11154                }
11155                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11156                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11157                    public void run() {
11158                        synchronized (ActivityManagerService.this) {
11159                            mDidUpdate = true;
11160                        }
11161                        writeLastDonePreBootReceivers(doneReceivers);
11162                        showBootMessage(mContext.getText(
11163                                R.string.android_upgrading_complete),
11164                                false);
11165                        systemReady(goingCallback);
11166                    }
11167                }, doneReceivers, UserHandle.USER_OWNER);
11168
11169                if (mWaitingUpdate) {
11170                    return;
11171                }
11172                mDidUpdate = true;
11173            }
11174
11175            mAppOpsService.systemReady();
11176            mSystemReady = true;
11177        }
11178
11179        ArrayList<ProcessRecord> procsToKill = null;
11180        synchronized(mPidsSelfLocked) {
11181            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11182                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11183                if (!isAllowedWhileBooting(proc.info)){
11184                    if (procsToKill == null) {
11185                        procsToKill = new ArrayList<ProcessRecord>();
11186                    }
11187                    procsToKill.add(proc);
11188                }
11189            }
11190        }
11191
11192        synchronized(this) {
11193            if (procsToKill != null) {
11194                for (int i=procsToKill.size()-1; i>=0; i--) {
11195                    ProcessRecord proc = procsToKill.get(i);
11196                    Slog.i(TAG, "Removing system update proc: " + proc);
11197                    removeProcessLocked(proc, true, false, "system update done");
11198                }
11199            }
11200
11201            // Now that we have cleaned up any update processes, we
11202            // are ready to start launching real processes and know that
11203            // we won't trample on them any more.
11204            mProcessesReady = true;
11205        }
11206
11207        Slog.i(TAG, "System now ready");
11208        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11209            SystemClock.uptimeMillis());
11210
11211        synchronized(this) {
11212            // Make sure we have no pre-ready processes sitting around.
11213
11214            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11215                ResolveInfo ri = mContext.getPackageManager()
11216                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11217                                STOCK_PM_FLAGS);
11218                CharSequence errorMsg = null;
11219                if (ri != null) {
11220                    ActivityInfo ai = ri.activityInfo;
11221                    ApplicationInfo app = ai.applicationInfo;
11222                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11223                        mTopAction = Intent.ACTION_FACTORY_TEST;
11224                        mTopData = null;
11225                        mTopComponent = new ComponentName(app.packageName,
11226                                ai.name);
11227                    } else {
11228                        errorMsg = mContext.getResources().getText(
11229                                com.android.internal.R.string.factorytest_not_system);
11230                    }
11231                } else {
11232                    errorMsg = mContext.getResources().getText(
11233                            com.android.internal.R.string.factorytest_no_action);
11234                }
11235                if (errorMsg != null) {
11236                    mTopAction = null;
11237                    mTopData = null;
11238                    mTopComponent = null;
11239                    Message msg = Message.obtain();
11240                    msg.what = SHOW_FACTORY_ERROR_MSG;
11241                    msg.getData().putCharSequence("msg", errorMsg);
11242                    mHandler.sendMessage(msg);
11243                }
11244            }
11245        }
11246
11247        retrieveSettings();
11248        loadResourcesOnSystemReady();
11249
11250        synchronized (this) {
11251            readGrantedUriPermissionsLocked();
11252        }
11253
11254        if (goingCallback != null) goingCallback.run();
11255
11256        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11257                Integer.toString(mCurrentUserId), mCurrentUserId);
11258        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11259                Integer.toString(mCurrentUserId), mCurrentUserId);
11260        mSystemServiceManager.startUser(mCurrentUserId);
11261
11262        synchronized (this) {
11263            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11264                try {
11265                    List apps = AppGlobals.getPackageManager().
11266                        getPersistentApplications(STOCK_PM_FLAGS);
11267                    if (apps != null) {
11268                        int N = apps.size();
11269                        int i;
11270                        for (i=0; i<N; i++) {
11271                            ApplicationInfo info
11272                                = (ApplicationInfo)apps.get(i);
11273                            if (info != null &&
11274                                    !info.packageName.equals("android")) {
11275                                addAppLocked(info, false, null /* ABI override */);
11276                            }
11277                        }
11278                    }
11279                } catch (RemoteException ex) {
11280                    // pm is in same process, this will never happen.
11281                }
11282            }
11283
11284            // Start up initial activity.
11285            mBooting = true;
11286            startHomeActivityLocked(mCurrentUserId);
11287
11288            try {
11289                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11290                    Message msg = Message.obtain();
11291                    msg.what = SHOW_UID_ERROR_MSG;
11292                    mHandler.sendMessage(msg);
11293                }
11294            } catch (RemoteException e) {
11295            }
11296
11297            long ident = Binder.clearCallingIdentity();
11298            try {
11299                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11300                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11301                        | Intent.FLAG_RECEIVER_FOREGROUND);
11302                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11303                broadcastIntentLocked(null, null, intent,
11304                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11305                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11306                intent = new Intent(Intent.ACTION_USER_STARTING);
11307                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11308                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11309                broadcastIntentLocked(null, null, intent,
11310                        null, new IIntentReceiver.Stub() {
11311                            @Override
11312                            public void performReceive(Intent intent, int resultCode, String data,
11313                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11314                                    throws RemoteException {
11315                            }
11316                        }, 0, null, null,
11317                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11318                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11319            } catch (Throwable t) {
11320                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11321            } finally {
11322                Binder.restoreCallingIdentity(ident);
11323            }
11324            mStackSupervisor.resumeTopActivitiesLocked();
11325            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11326        }
11327    }
11328
11329    private boolean makeAppCrashingLocked(ProcessRecord app,
11330            String shortMsg, String longMsg, String stackTrace) {
11331        app.crashing = true;
11332        app.crashingReport = generateProcessError(app,
11333                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11334        startAppProblemLocked(app);
11335        app.stopFreezingAllLocked();
11336        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11337    }
11338
11339    private void makeAppNotRespondingLocked(ProcessRecord app,
11340            String activity, String shortMsg, String longMsg) {
11341        app.notResponding = true;
11342        app.notRespondingReport = generateProcessError(app,
11343                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11344                activity, shortMsg, longMsg, null);
11345        startAppProblemLocked(app);
11346        app.stopFreezingAllLocked();
11347    }
11348
11349    /**
11350     * Generate a process error record, suitable for attachment to a ProcessRecord.
11351     *
11352     * @param app The ProcessRecord in which the error occurred.
11353     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11354     *                      ActivityManager.AppErrorStateInfo
11355     * @param activity The activity associated with the crash, if known.
11356     * @param shortMsg Short message describing the crash.
11357     * @param longMsg Long message describing the crash.
11358     * @param stackTrace Full crash stack trace, may be null.
11359     *
11360     * @return Returns a fully-formed AppErrorStateInfo record.
11361     */
11362    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11363            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11364        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11365
11366        report.condition = condition;
11367        report.processName = app.processName;
11368        report.pid = app.pid;
11369        report.uid = app.info.uid;
11370        report.tag = activity;
11371        report.shortMsg = shortMsg;
11372        report.longMsg = longMsg;
11373        report.stackTrace = stackTrace;
11374
11375        return report;
11376    }
11377
11378    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11379        synchronized (this) {
11380            app.crashing = false;
11381            app.crashingReport = null;
11382            app.notResponding = false;
11383            app.notRespondingReport = null;
11384            if (app.anrDialog == fromDialog) {
11385                app.anrDialog = null;
11386            }
11387            if (app.waitDialog == fromDialog) {
11388                app.waitDialog = null;
11389            }
11390            if (app.pid > 0 && app.pid != MY_PID) {
11391                handleAppCrashLocked(app, null, null, null);
11392                app.kill("user request after error", true);
11393            }
11394        }
11395    }
11396
11397    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11398            String stackTrace) {
11399        long now = SystemClock.uptimeMillis();
11400
11401        Long crashTime;
11402        if (!app.isolated) {
11403            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11404        } else {
11405            crashTime = null;
11406        }
11407        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11408            // This process loses!
11409            Slog.w(TAG, "Process " + app.info.processName
11410                    + " has crashed too many times: killing!");
11411            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11412                    app.userId, app.info.processName, app.uid);
11413            mStackSupervisor.handleAppCrashLocked(app);
11414            if (!app.persistent) {
11415                // We don't want to start this process again until the user
11416                // explicitly does so...  but for persistent process, we really
11417                // need to keep it running.  If a persistent process is actually
11418                // repeatedly crashing, then badness for everyone.
11419                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11420                        app.info.processName);
11421                if (!app.isolated) {
11422                    // XXX We don't have a way to mark isolated processes
11423                    // as bad, since they don't have a peristent identity.
11424                    mBadProcesses.put(app.info.processName, app.uid,
11425                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11426                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11427                }
11428                app.bad = true;
11429                app.removed = true;
11430                // Don't let services in this process be restarted and potentially
11431                // annoy the user repeatedly.  Unless it is persistent, since those
11432                // processes run critical code.
11433                removeProcessLocked(app, false, false, "crash");
11434                mStackSupervisor.resumeTopActivitiesLocked();
11435                return false;
11436            }
11437            mStackSupervisor.resumeTopActivitiesLocked();
11438        } else {
11439            mStackSupervisor.finishTopRunningActivityLocked(app);
11440        }
11441
11442        // Bump up the crash count of any services currently running in the proc.
11443        for (int i=app.services.size()-1; i>=0; i--) {
11444            // Any services running in the application need to be placed
11445            // back in the pending list.
11446            ServiceRecord sr = app.services.valueAt(i);
11447            sr.crashCount++;
11448        }
11449
11450        // If the crashing process is what we consider to be the "home process" and it has been
11451        // replaced by a third-party app, clear the package preferred activities from packages
11452        // with a home activity running in the process to prevent a repeatedly crashing app
11453        // from blocking the user to manually clear the list.
11454        final ArrayList<ActivityRecord> activities = app.activities;
11455        if (app == mHomeProcess && activities.size() > 0
11456                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11457            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11458                final ActivityRecord r = activities.get(activityNdx);
11459                if (r.isHomeActivity()) {
11460                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11461                    try {
11462                        ActivityThread.getPackageManager()
11463                                .clearPackagePreferredActivities(r.packageName);
11464                    } catch (RemoteException c) {
11465                        // pm is in same process, this will never happen.
11466                    }
11467                }
11468            }
11469        }
11470
11471        if (!app.isolated) {
11472            // XXX Can't keep track of crash times for isolated processes,
11473            // because they don't have a perisistent identity.
11474            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11475        }
11476
11477        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11478        return true;
11479    }
11480
11481    void startAppProblemLocked(ProcessRecord app) {
11482        // If this app is not running under the current user, then we
11483        // can't give it a report button because that would require
11484        // launching the report UI under a different user.
11485        app.errorReportReceiver = null;
11486
11487        for (int userId : mCurrentProfileIds) {
11488            if (app.userId == userId) {
11489                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11490                        mContext, app.info.packageName, app.info.flags);
11491            }
11492        }
11493        skipCurrentReceiverLocked(app);
11494    }
11495
11496    void skipCurrentReceiverLocked(ProcessRecord app) {
11497        for (BroadcastQueue queue : mBroadcastQueues) {
11498            queue.skipCurrentReceiverLocked(app);
11499        }
11500    }
11501
11502    /**
11503     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11504     * The application process will exit immediately after this call returns.
11505     * @param app object of the crashing app, null for the system server
11506     * @param crashInfo describing the exception
11507     */
11508    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11509        ProcessRecord r = findAppProcess(app, "Crash");
11510        final String processName = app == null ? "system_server"
11511                : (r == null ? "unknown" : r.processName);
11512
11513        handleApplicationCrashInner("crash", r, processName, crashInfo);
11514    }
11515
11516    /* Native crash reporting uses this inner version because it needs to be somewhat
11517     * decoupled from the AM-managed cleanup lifecycle
11518     */
11519    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11520            ApplicationErrorReport.CrashInfo crashInfo) {
11521        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11522                UserHandle.getUserId(Binder.getCallingUid()), processName,
11523                r == null ? -1 : r.info.flags,
11524                crashInfo.exceptionClassName,
11525                crashInfo.exceptionMessage,
11526                crashInfo.throwFileName,
11527                crashInfo.throwLineNumber);
11528
11529        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11530
11531        crashApplication(r, crashInfo);
11532    }
11533
11534    public void handleApplicationStrictModeViolation(
11535            IBinder app,
11536            int violationMask,
11537            StrictMode.ViolationInfo info) {
11538        ProcessRecord r = findAppProcess(app, "StrictMode");
11539        if (r == null) {
11540            return;
11541        }
11542
11543        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11544            Integer stackFingerprint = info.hashCode();
11545            boolean logIt = true;
11546            synchronized (mAlreadyLoggedViolatedStacks) {
11547                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11548                    logIt = false;
11549                    // TODO: sub-sample into EventLog for these, with
11550                    // the info.durationMillis?  Then we'd get
11551                    // the relative pain numbers, without logging all
11552                    // the stack traces repeatedly.  We'd want to do
11553                    // likewise in the client code, which also does
11554                    // dup suppression, before the Binder call.
11555                } else {
11556                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11557                        mAlreadyLoggedViolatedStacks.clear();
11558                    }
11559                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11560                }
11561            }
11562            if (logIt) {
11563                logStrictModeViolationToDropBox(r, info);
11564            }
11565        }
11566
11567        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11568            AppErrorResult result = new AppErrorResult();
11569            synchronized (this) {
11570                final long origId = Binder.clearCallingIdentity();
11571
11572                Message msg = Message.obtain();
11573                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11574                HashMap<String, Object> data = new HashMap<String, Object>();
11575                data.put("result", result);
11576                data.put("app", r);
11577                data.put("violationMask", violationMask);
11578                data.put("info", info);
11579                msg.obj = data;
11580                mHandler.sendMessage(msg);
11581
11582                Binder.restoreCallingIdentity(origId);
11583            }
11584            int res = result.get();
11585            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11586        }
11587    }
11588
11589    // Depending on the policy in effect, there could be a bunch of
11590    // these in quick succession so we try to batch these together to
11591    // minimize disk writes, number of dropbox entries, and maximize
11592    // compression, by having more fewer, larger records.
11593    private void logStrictModeViolationToDropBox(
11594            ProcessRecord process,
11595            StrictMode.ViolationInfo info) {
11596        if (info == null) {
11597            return;
11598        }
11599        final boolean isSystemApp = process == null ||
11600                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11601                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11602        final String processName = process == null ? "unknown" : process.processName;
11603        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11604        final DropBoxManager dbox = (DropBoxManager)
11605                mContext.getSystemService(Context.DROPBOX_SERVICE);
11606
11607        // Exit early if the dropbox isn't configured to accept this report type.
11608        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11609
11610        boolean bufferWasEmpty;
11611        boolean needsFlush;
11612        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11613        synchronized (sb) {
11614            bufferWasEmpty = sb.length() == 0;
11615            appendDropBoxProcessHeaders(process, processName, sb);
11616            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11617            sb.append("System-App: ").append(isSystemApp).append("\n");
11618            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11619            if (info.violationNumThisLoop != 0) {
11620                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11621            }
11622            if (info.numAnimationsRunning != 0) {
11623                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11624            }
11625            if (info.broadcastIntentAction != null) {
11626                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11627            }
11628            if (info.durationMillis != -1) {
11629                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11630            }
11631            if (info.numInstances != -1) {
11632                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11633            }
11634            if (info.tags != null) {
11635                for (String tag : info.tags) {
11636                    sb.append("Span-Tag: ").append(tag).append("\n");
11637                }
11638            }
11639            sb.append("\n");
11640            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11641                sb.append(info.crashInfo.stackTrace);
11642            }
11643            sb.append("\n");
11644
11645            // Only buffer up to ~64k.  Various logging bits truncate
11646            // things at 128k.
11647            needsFlush = (sb.length() > 64 * 1024);
11648        }
11649
11650        // Flush immediately if the buffer's grown too large, or this
11651        // is a non-system app.  Non-system apps are isolated with a
11652        // different tag & policy and not batched.
11653        //
11654        // Batching is useful during internal testing with
11655        // StrictMode settings turned up high.  Without batching,
11656        // thousands of separate files could be created on boot.
11657        if (!isSystemApp || needsFlush) {
11658            new Thread("Error dump: " + dropboxTag) {
11659                @Override
11660                public void run() {
11661                    String report;
11662                    synchronized (sb) {
11663                        report = sb.toString();
11664                        sb.delete(0, sb.length());
11665                        sb.trimToSize();
11666                    }
11667                    if (report.length() != 0) {
11668                        dbox.addText(dropboxTag, report);
11669                    }
11670                }
11671            }.start();
11672            return;
11673        }
11674
11675        // System app batching:
11676        if (!bufferWasEmpty) {
11677            // An existing dropbox-writing thread is outstanding, so
11678            // we don't need to start it up.  The existing thread will
11679            // catch the buffer appends we just did.
11680            return;
11681        }
11682
11683        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11684        // (After this point, we shouldn't access AMS internal data structures.)
11685        new Thread("Error dump: " + dropboxTag) {
11686            @Override
11687            public void run() {
11688                // 5 second sleep to let stacks arrive and be batched together
11689                try {
11690                    Thread.sleep(5000);  // 5 seconds
11691                } catch (InterruptedException e) {}
11692
11693                String errorReport;
11694                synchronized (mStrictModeBuffer) {
11695                    errorReport = mStrictModeBuffer.toString();
11696                    if (errorReport.length() == 0) {
11697                        return;
11698                    }
11699                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11700                    mStrictModeBuffer.trimToSize();
11701                }
11702                dbox.addText(dropboxTag, errorReport);
11703            }
11704        }.start();
11705    }
11706
11707    /**
11708     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11709     * @param app object of the crashing app, null for the system server
11710     * @param tag reported by the caller
11711     * @param system whether this wtf is coming from the system
11712     * @param crashInfo describing the context of the error
11713     * @return true if the process should exit immediately (WTF is fatal)
11714     */
11715    public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11716            final ApplicationErrorReport.CrashInfo crashInfo) {
11717        final int callingUid = Binder.getCallingUid();
11718        final int callingPid = Binder.getCallingPid();
11719
11720        if (system) {
11721            // If this is coming from the system, we could very well have low-level
11722            // system locks held, so we want to do this all asynchronously.  And we
11723            // never want this to become fatal, so there is that too.
11724            mHandler.post(new Runnable() {
11725                @Override public void run() {
11726                    handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11727                }
11728            });
11729            return false;
11730        }
11731
11732        final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11733                crashInfo);
11734
11735        if (r != null && r.pid != Process.myPid() &&
11736                Settings.Global.getInt(mContext.getContentResolver(),
11737                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11738            crashApplication(r, crashInfo);
11739            return true;
11740        } else {
11741            return false;
11742        }
11743    }
11744
11745    ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11746            final ApplicationErrorReport.CrashInfo crashInfo) {
11747        final ProcessRecord r = findAppProcess(app, "WTF");
11748        final String processName = app == null ? "system_server"
11749                : (r == null ? "unknown" : r.processName);
11750
11751        EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11752                processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11753
11754        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11755
11756        return r;
11757    }
11758
11759    /**
11760     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11761     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11762     */
11763    private ProcessRecord findAppProcess(IBinder app, String reason) {
11764        if (app == null) {
11765            return null;
11766        }
11767
11768        synchronized (this) {
11769            final int NP = mProcessNames.getMap().size();
11770            for (int ip=0; ip<NP; ip++) {
11771                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11772                final int NA = apps.size();
11773                for (int ia=0; ia<NA; ia++) {
11774                    ProcessRecord p = apps.valueAt(ia);
11775                    if (p.thread != null && p.thread.asBinder() == app) {
11776                        return p;
11777                    }
11778                }
11779            }
11780
11781            Slog.w(TAG, "Can't find mystery application for " + reason
11782                    + " from pid=" + Binder.getCallingPid()
11783                    + " uid=" + Binder.getCallingUid() + ": " + app);
11784            return null;
11785        }
11786    }
11787
11788    /**
11789     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11790     * to append various headers to the dropbox log text.
11791     */
11792    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11793            StringBuilder sb) {
11794        // Watchdog thread ends up invoking this function (with
11795        // a null ProcessRecord) to add the stack file to dropbox.
11796        // Do not acquire a lock on this (am) in such cases, as it
11797        // could cause a potential deadlock, if and when watchdog
11798        // is invoked due to unavailability of lock on am and it
11799        // would prevent watchdog from killing system_server.
11800        if (process == null) {
11801            sb.append("Process: ").append(processName).append("\n");
11802            return;
11803        }
11804        // Note: ProcessRecord 'process' is guarded by the service
11805        // instance.  (notably process.pkgList, which could otherwise change
11806        // concurrently during execution of this method)
11807        synchronized (this) {
11808            sb.append("Process: ").append(processName).append("\n");
11809            int flags = process.info.flags;
11810            IPackageManager pm = AppGlobals.getPackageManager();
11811            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11812            for (int ip=0; ip<process.pkgList.size(); ip++) {
11813                String pkg = process.pkgList.keyAt(ip);
11814                sb.append("Package: ").append(pkg);
11815                try {
11816                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11817                    if (pi != null) {
11818                        sb.append(" v").append(pi.versionCode);
11819                        if (pi.versionName != null) {
11820                            sb.append(" (").append(pi.versionName).append(")");
11821                        }
11822                    }
11823                } catch (RemoteException e) {
11824                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11825                }
11826                sb.append("\n");
11827            }
11828        }
11829    }
11830
11831    private static String processClass(ProcessRecord process) {
11832        if (process == null || process.pid == MY_PID) {
11833            return "system_server";
11834        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11835            return "system_app";
11836        } else {
11837            return "data_app";
11838        }
11839    }
11840
11841    /**
11842     * Write a description of an error (crash, WTF, ANR) to the drop box.
11843     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11844     * @param process which caused the error, null means the system server
11845     * @param activity which triggered the error, null if unknown
11846     * @param parent activity related to the error, null if unknown
11847     * @param subject line related to the error, null if absent
11848     * @param report in long form describing the error, null if absent
11849     * @param logFile to include in the report, null if none
11850     * @param crashInfo giving an application stack trace, null if absent
11851     */
11852    public void addErrorToDropBox(String eventType,
11853            ProcessRecord process, String processName, ActivityRecord activity,
11854            ActivityRecord parent, String subject,
11855            final String report, final File logFile,
11856            final ApplicationErrorReport.CrashInfo crashInfo) {
11857        // NOTE -- this must never acquire the ActivityManagerService lock,
11858        // otherwise the watchdog may be prevented from resetting the system.
11859
11860        final String dropboxTag = processClass(process) + "_" + eventType;
11861        final DropBoxManager dbox = (DropBoxManager)
11862                mContext.getSystemService(Context.DROPBOX_SERVICE);
11863
11864        // Exit early if the dropbox isn't configured to accept this report type.
11865        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11866
11867        final StringBuilder sb = new StringBuilder(1024);
11868        appendDropBoxProcessHeaders(process, processName, sb);
11869        if (activity != null) {
11870            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11871        }
11872        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11873            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11874        }
11875        if (parent != null && parent != activity) {
11876            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11877        }
11878        if (subject != null) {
11879            sb.append("Subject: ").append(subject).append("\n");
11880        }
11881        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11882        if (Debug.isDebuggerConnected()) {
11883            sb.append("Debugger: Connected\n");
11884        }
11885        sb.append("\n");
11886
11887        // Do the rest in a worker thread to avoid blocking the caller on I/O
11888        // (After this point, we shouldn't access AMS internal data structures.)
11889        Thread worker = new Thread("Error dump: " + dropboxTag) {
11890            @Override
11891            public void run() {
11892                if (report != null) {
11893                    sb.append(report);
11894                }
11895                if (logFile != null) {
11896                    try {
11897                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11898                                    "\n\n[[TRUNCATED]]"));
11899                    } catch (IOException e) {
11900                        Slog.e(TAG, "Error reading " + logFile, e);
11901                    }
11902                }
11903                if (crashInfo != null && crashInfo.stackTrace != null) {
11904                    sb.append(crashInfo.stackTrace);
11905                }
11906
11907                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11908                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11909                if (lines > 0) {
11910                    sb.append("\n");
11911
11912                    // Merge several logcat streams, and take the last N lines
11913                    InputStreamReader input = null;
11914                    try {
11915                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11916                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11917                                "-b", "crash",
11918                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11919
11920                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11921                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11922                        input = new InputStreamReader(logcat.getInputStream());
11923
11924                        int num;
11925                        char[] buf = new char[8192];
11926                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11927                    } catch (IOException e) {
11928                        Slog.e(TAG, "Error running logcat", e);
11929                    } finally {
11930                        if (input != null) try { input.close(); } catch (IOException e) {}
11931                    }
11932                }
11933
11934                dbox.addText(dropboxTag, sb.toString());
11935            }
11936        };
11937
11938        if (process == null) {
11939            // If process is null, we are being called from some internal code
11940            // and may be about to die -- run this synchronously.
11941            worker.run();
11942        } else {
11943            worker.start();
11944        }
11945    }
11946
11947    /**
11948     * Bring up the "unexpected error" dialog box for a crashing app.
11949     * Deal with edge cases (intercepts from instrumented applications,
11950     * ActivityController, error intent receivers, that sort of thing).
11951     * @param r the application crashing
11952     * @param crashInfo describing the failure
11953     */
11954    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11955        long timeMillis = System.currentTimeMillis();
11956        String shortMsg = crashInfo.exceptionClassName;
11957        String longMsg = crashInfo.exceptionMessage;
11958        String stackTrace = crashInfo.stackTrace;
11959        if (shortMsg != null && longMsg != null) {
11960            longMsg = shortMsg + ": " + longMsg;
11961        } else if (shortMsg != null) {
11962            longMsg = shortMsg;
11963        }
11964
11965        AppErrorResult result = new AppErrorResult();
11966        synchronized (this) {
11967            if (mController != null) {
11968                try {
11969                    String name = r != null ? r.processName : null;
11970                    int pid = r != null ? r.pid : Binder.getCallingPid();
11971                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11972                    if (!mController.appCrashed(name, pid,
11973                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11974                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11975                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11976                            Slog.w(TAG, "Skip killing native crashed app " + name
11977                                    + "(" + pid + ") during testing");
11978                        } else {
11979                            Slog.w(TAG, "Force-killing crashed app " + name
11980                                    + " at watcher's request");
11981                            if (r != null) {
11982                                r.kill("crash", true);
11983                            } else {
11984                                // Huh.
11985                                Process.killProcess(pid);
11986                                Process.killProcessGroup(uid, pid);
11987                            }
11988                        }
11989                        return;
11990                    }
11991                } catch (RemoteException e) {
11992                    mController = null;
11993                    Watchdog.getInstance().setActivityController(null);
11994                }
11995            }
11996
11997            final long origId = Binder.clearCallingIdentity();
11998
11999            // If this process is running instrumentation, finish it.
12000            if (r != null && r.instrumentationClass != null) {
12001                Slog.w(TAG, "Error in app " + r.processName
12002                      + " running instrumentation " + r.instrumentationClass + ":");
12003                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
12004                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
12005                Bundle info = new Bundle();
12006                info.putString("shortMsg", shortMsg);
12007                info.putString("longMsg", longMsg);
12008                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12009                Binder.restoreCallingIdentity(origId);
12010                return;
12011            }
12012
12013            // If we can't identify the process or it's already exceeded its crash quota,
12014            // quit right away without showing a crash dialog.
12015            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12016                Binder.restoreCallingIdentity(origId);
12017                return;
12018            }
12019
12020            Message msg = Message.obtain();
12021            msg.what = SHOW_ERROR_MSG;
12022            HashMap data = new HashMap();
12023            data.put("result", result);
12024            data.put("app", r);
12025            msg.obj = data;
12026            mHandler.sendMessage(msg);
12027
12028            Binder.restoreCallingIdentity(origId);
12029        }
12030
12031        int res = result.get();
12032
12033        Intent appErrorIntent = null;
12034        synchronized (this) {
12035            if (r != null && !r.isolated) {
12036                // XXX Can't keep track of crash time for isolated processes,
12037                // since they don't have a persistent identity.
12038                mProcessCrashTimes.put(r.info.processName, r.uid,
12039                        SystemClock.uptimeMillis());
12040            }
12041            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12042                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12043            }
12044        }
12045
12046        if (appErrorIntent != null) {
12047            try {
12048                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12049            } catch (ActivityNotFoundException e) {
12050                Slog.w(TAG, "bug report receiver dissappeared", e);
12051            }
12052        }
12053    }
12054
12055    Intent createAppErrorIntentLocked(ProcessRecord r,
12056            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12057        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12058        if (report == null) {
12059            return null;
12060        }
12061        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12062        result.setComponent(r.errorReportReceiver);
12063        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12064        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12065        return result;
12066    }
12067
12068    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12069            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12070        if (r.errorReportReceiver == null) {
12071            return null;
12072        }
12073
12074        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12075            return null;
12076        }
12077
12078        ApplicationErrorReport report = new ApplicationErrorReport();
12079        report.packageName = r.info.packageName;
12080        report.installerPackageName = r.errorReportReceiver.getPackageName();
12081        report.processName = r.processName;
12082        report.time = timeMillis;
12083        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12084
12085        if (r.crashing || r.forceCrashReport) {
12086            report.type = ApplicationErrorReport.TYPE_CRASH;
12087            report.crashInfo = crashInfo;
12088        } else if (r.notResponding) {
12089            report.type = ApplicationErrorReport.TYPE_ANR;
12090            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12091
12092            report.anrInfo.activity = r.notRespondingReport.tag;
12093            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12094            report.anrInfo.info = r.notRespondingReport.longMsg;
12095        }
12096
12097        return report;
12098    }
12099
12100    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12101        enforceNotIsolatedCaller("getProcessesInErrorState");
12102        // assume our apps are happy - lazy create the list
12103        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12104
12105        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12106                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12107        int userId = UserHandle.getUserId(Binder.getCallingUid());
12108
12109        synchronized (this) {
12110
12111            // iterate across all processes
12112            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12113                ProcessRecord app = mLruProcesses.get(i);
12114                if (!allUsers && app.userId != userId) {
12115                    continue;
12116                }
12117                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12118                    // This one's in trouble, so we'll generate a report for it
12119                    // crashes are higher priority (in case there's a crash *and* an anr)
12120                    ActivityManager.ProcessErrorStateInfo report = null;
12121                    if (app.crashing) {
12122                        report = app.crashingReport;
12123                    } else if (app.notResponding) {
12124                        report = app.notRespondingReport;
12125                    }
12126
12127                    if (report != null) {
12128                        if (errList == null) {
12129                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12130                        }
12131                        errList.add(report);
12132                    } else {
12133                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12134                                " crashing = " + app.crashing +
12135                                " notResponding = " + app.notResponding);
12136                    }
12137                }
12138            }
12139        }
12140
12141        return errList;
12142    }
12143
12144    static int procStateToImportance(int procState, int memAdj,
12145            ActivityManager.RunningAppProcessInfo currApp) {
12146        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12147        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12148            currApp.lru = memAdj;
12149        } else {
12150            currApp.lru = 0;
12151        }
12152        return imp;
12153    }
12154
12155    private void fillInProcMemInfo(ProcessRecord app,
12156            ActivityManager.RunningAppProcessInfo outInfo) {
12157        outInfo.pid = app.pid;
12158        outInfo.uid = app.info.uid;
12159        if (mHeavyWeightProcess == app) {
12160            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12161        }
12162        if (app.persistent) {
12163            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12164        }
12165        if (app.activities.size() > 0) {
12166            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12167        }
12168        outInfo.lastTrimLevel = app.trimMemoryLevel;
12169        int adj = app.curAdj;
12170        int procState = app.curProcState;
12171        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12172        outInfo.importanceReasonCode = app.adjTypeCode;
12173        outInfo.processState = app.curProcState;
12174    }
12175
12176    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12177        enforceNotIsolatedCaller("getRunningAppProcesses");
12178        // Lazy instantiation of list
12179        List<ActivityManager.RunningAppProcessInfo> runList = null;
12180        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12181                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12182        int userId = UserHandle.getUserId(Binder.getCallingUid());
12183        synchronized (this) {
12184            // Iterate across all processes
12185            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12186                ProcessRecord app = mLruProcesses.get(i);
12187                if (!allUsers && app.userId != userId) {
12188                    continue;
12189                }
12190                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12191                    // Generate process state info for running application
12192                    ActivityManager.RunningAppProcessInfo currApp =
12193                        new ActivityManager.RunningAppProcessInfo(app.processName,
12194                                app.pid, app.getPackageList());
12195                    fillInProcMemInfo(app, currApp);
12196                    if (app.adjSource instanceof ProcessRecord) {
12197                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12198                        currApp.importanceReasonImportance =
12199                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12200                                        app.adjSourceProcState);
12201                    } else if (app.adjSource instanceof ActivityRecord) {
12202                        ActivityRecord r = (ActivityRecord)app.adjSource;
12203                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12204                    }
12205                    if (app.adjTarget instanceof ComponentName) {
12206                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12207                    }
12208                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12209                    //        + " lru=" + currApp.lru);
12210                    if (runList == null) {
12211                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12212                    }
12213                    runList.add(currApp);
12214                }
12215            }
12216        }
12217        return runList;
12218    }
12219
12220    public List<ApplicationInfo> getRunningExternalApplications() {
12221        enforceNotIsolatedCaller("getRunningExternalApplications");
12222        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12223        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12224        if (runningApps != null && runningApps.size() > 0) {
12225            Set<String> extList = new HashSet<String>();
12226            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12227                if (app.pkgList != null) {
12228                    for (String pkg : app.pkgList) {
12229                        extList.add(pkg);
12230                    }
12231                }
12232            }
12233            IPackageManager pm = AppGlobals.getPackageManager();
12234            for (String pkg : extList) {
12235                try {
12236                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12237                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12238                        retList.add(info);
12239                    }
12240                } catch (RemoteException e) {
12241                }
12242            }
12243        }
12244        return retList;
12245    }
12246
12247    @Override
12248    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12249        enforceNotIsolatedCaller("getMyMemoryState");
12250        synchronized (this) {
12251            ProcessRecord proc;
12252            synchronized (mPidsSelfLocked) {
12253                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12254            }
12255            fillInProcMemInfo(proc, outInfo);
12256        }
12257    }
12258
12259    @Override
12260    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12261        if (checkCallingPermission(android.Manifest.permission.DUMP)
12262                != PackageManager.PERMISSION_GRANTED) {
12263            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12264                    + Binder.getCallingPid()
12265                    + ", uid=" + Binder.getCallingUid()
12266                    + " without permission "
12267                    + android.Manifest.permission.DUMP);
12268            return;
12269        }
12270
12271        boolean dumpAll = false;
12272        boolean dumpClient = false;
12273        String dumpPackage = null;
12274
12275        int opti = 0;
12276        while (opti < args.length) {
12277            String opt = args[opti];
12278            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12279                break;
12280            }
12281            opti++;
12282            if ("-a".equals(opt)) {
12283                dumpAll = true;
12284            } else if ("-c".equals(opt)) {
12285                dumpClient = true;
12286            } else if ("-h".equals(opt)) {
12287                pw.println("Activity manager dump options:");
12288                pw.println("  [-a] [-c] [-h] [cmd] ...");
12289                pw.println("  cmd may be one of:");
12290                pw.println("    a[ctivities]: activity stack state");
12291                pw.println("    r[recents]: recent activities state");
12292                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12293                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12294                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12295                pw.println("    o[om]: out of memory management");
12296                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12297                pw.println("    provider [COMP_SPEC]: provider client-side state");
12298                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12299                pw.println("    service [COMP_SPEC]: service client-side state");
12300                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12301                pw.println("    all: dump all activities");
12302                pw.println("    top: dump the top activity");
12303                pw.println("    write: write all pending state to storage");
12304                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12305                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12306                pw.println("    a partial substring in a component name, a");
12307                pw.println("    hex object identifier.");
12308                pw.println("  -a: include all available server state.");
12309                pw.println("  -c: include client state.");
12310                return;
12311            } else {
12312                pw.println("Unknown argument: " + opt + "; use -h for help");
12313            }
12314        }
12315
12316        long origId = Binder.clearCallingIdentity();
12317        boolean more = false;
12318        // Is the caller requesting to dump a particular piece of data?
12319        if (opti < args.length) {
12320            String cmd = args[opti];
12321            opti++;
12322            if ("activities".equals(cmd) || "a".equals(cmd)) {
12323                synchronized (this) {
12324                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12325                }
12326            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12327                synchronized (this) {
12328                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12329                }
12330            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12331                String[] newArgs;
12332                String name;
12333                if (opti >= args.length) {
12334                    name = null;
12335                    newArgs = EMPTY_STRING_ARRAY;
12336                } else {
12337                    name = args[opti];
12338                    opti++;
12339                    newArgs = new String[args.length - opti];
12340                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12341                            args.length - opti);
12342                }
12343                synchronized (this) {
12344                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12345                }
12346            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12347                String[] newArgs;
12348                String name;
12349                if (opti >= args.length) {
12350                    name = null;
12351                    newArgs = EMPTY_STRING_ARRAY;
12352                } else {
12353                    name = args[opti];
12354                    opti++;
12355                    newArgs = new String[args.length - opti];
12356                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12357                            args.length - opti);
12358                }
12359                synchronized (this) {
12360                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12361                }
12362            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12363                String[] newArgs;
12364                String name;
12365                if (opti >= args.length) {
12366                    name = null;
12367                    newArgs = EMPTY_STRING_ARRAY;
12368                } else {
12369                    name = args[opti];
12370                    opti++;
12371                    newArgs = new String[args.length - opti];
12372                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12373                            args.length - opti);
12374                }
12375                synchronized (this) {
12376                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12377                }
12378            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12379                synchronized (this) {
12380                    dumpOomLocked(fd, pw, args, opti, true);
12381                }
12382            } else if ("provider".equals(cmd)) {
12383                String[] newArgs;
12384                String name;
12385                if (opti >= args.length) {
12386                    name = null;
12387                    newArgs = EMPTY_STRING_ARRAY;
12388                } else {
12389                    name = args[opti];
12390                    opti++;
12391                    newArgs = new String[args.length - opti];
12392                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12393                }
12394                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12395                    pw.println("No providers match: " + name);
12396                    pw.println("Use -h for help.");
12397                }
12398            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12399                synchronized (this) {
12400                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12401                }
12402            } else if ("service".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                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12416                    pw.println("No services match: " + name);
12417                    pw.println("Use -h for help.");
12418                }
12419            } else if ("package".equals(cmd)) {
12420                String[] newArgs;
12421                if (opti >= args.length) {
12422                    pw.println("package: no package name specified");
12423                    pw.println("Use -h for help.");
12424                } else {
12425                    dumpPackage = 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                    args = newArgs;
12431                    opti = 0;
12432                    more = true;
12433                }
12434            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12435                synchronized (this) {
12436                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12437                }
12438            } else if ("write".equals(cmd)) {
12439                mTaskPersister.flush();
12440                pw.println("All tasks persisted.");
12441                return;
12442            } else {
12443                // Dumping a single activity?
12444                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12445                    pw.println("Bad activity command, or no activities match: " + cmd);
12446                    pw.println("Use -h for help.");
12447                }
12448            }
12449            if (!more) {
12450                Binder.restoreCallingIdentity(origId);
12451                return;
12452            }
12453        }
12454
12455        // No piece of data specified, dump everything.
12456        synchronized (this) {
12457            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12458            pw.println();
12459            if (dumpAll) {
12460                pw.println("-------------------------------------------------------------------------------");
12461            }
12462            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12463            pw.println();
12464            if (dumpAll) {
12465                pw.println("-------------------------------------------------------------------------------");
12466            }
12467            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12468            pw.println();
12469            if (dumpAll) {
12470                pw.println("-------------------------------------------------------------------------------");
12471            }
12472            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12473            pw.println();
12474            if (dumpAll) {
12475                pw.println("-------------------------------------------------------------------------------");
12476            }
12477            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12478            pw.println();
12479            if (dumpAll) {
12480                pw.println("-------------------------------------------------------------------------------");
12481            }
12482            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12483            pw.println();
12484            if (dumpAll) {
12485                pw.println("-------------------------------------------------------------------------------");
12486            }
12487            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12488        }
12489        Binder.restoreCallingIdentity(origId);
12490    }
12491
12492    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12493            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12494        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12495
12496        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12497                dumpPackage);
12498        boolean needSep = printedAnything;
12499
12500        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12501                dumpPackage, needSep, "  mFocusedActivity: ");
12502        if (printed) {
12503            printedAnything = true;
12504            needSep = false;
12505        }
12506
12507        if (dumpPackage == null) {
12508            if (needSep) {
12509                pw.println();
12510            }
12511            needSep = true;
12512            printedAnything = true;
12513            mStackSupervisor.dump(pw, "  ");
12514        }
12515
12516        if (!printedAnything) {
12517            pw.println("  (nothing)");
12518        }
12519    }
12520
12521    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12522            int opti, boolean dumpAll, String dumpPackage) {
12523        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12524
12525        boolean printedAnything = false;
12526
12527        if (mRecentTasks != null && mRecentTasks.size() > 0) {
12528            boolean printedHeader = false;
12529
12530            final int N = mRecentTasks.size();
12531            for (int i=0; i<N; i++) {
12532                TaskRecord tr = mRecentTasks.get(i);
12533                if (dumpPackage != null) {
12534                    if (tr.realActivity == null ||
12535                            !dumpPackage.equals(tr.realActivity)) {
12536                        continue;
12537                    }
12538                }
12539                if (!printedHeader) {
12540                    pw.println("  Recent tasks:");
12541                    printedHeader = true;
12542                    printedAnything = true;
12543                }
12544                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12545                        pw.println(tr);
12546                if (dumpAll) {
12547                    mRecentTasks.get(i).dump(pw, "    ");
12548                }
12549            }
12550        }
12551
12552        if (!printedAnything) {
12553            pw.println("  (nothing)");
12554        }
12555    }
12556
12557    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12558            int opti, boolean dumpAll, String dumpPackage) {
12559        boolean needSep = false;
12560        boolean printedAnything = false;
12561        int numPers = 0;
12562
12563        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12564
12565        if (dumpAll) {
12566            final int NP = mProcessNames.getMap().size();
12567            for (int ip=0; ip<NP; ip++) {
12568                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12569                final int NA = procs.size();
12570                for (int ia=0; ia<NA; ia++) {
12571                    ProcessRecord r = procs.valueAt(ia);
12572                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12573                        continue;
12574                    }
12575                    if (!needSep) {
12576                        pw.println("  All known processes:");
12577                        needSep = true;
12578                        printedAnything = true;
12579                    }
12580                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12581                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12582                        pw.print(" "); pw.println(r);
12583                    r.dump(pw, "    ");
12584                    if (r.persistent) {
12585                        numPers++;
12586                    }
12587                }
12588            }
12589        }
12590
12591        if (mIsolatedProcesses.size() > 0) {
12592            boolean printed = false;
12593            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12594                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12595                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12596                    continue;
12597                }
12598                if (!printed) {
12599                    if (needSep) {
12600                        pw.println();
12601                    }
12602                    pw.println("  Isolated process list (sorted by uid):");
12603                    printedAnything = true;
12604                    printed = true;
12605                    needSep = true;
12606                }
12607                pw.println(String.format("%sIsolated #%2d: %s",
12608                        "    ", i, r.toString()));
12609            }
12610        }
12611
12612        if (mLruProcesses.size() > 0) {
12613            if (needSep) {
12614                pw.println();
12615            }
12616            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12617                    pw.print(" total, non-act at ");
12618                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12619                    pw.print(", non-svc at ");
12620                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12621                    pw.println("):");
12622            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12623            needSep = true;
12624            printedAnything = true;
12625        }
12626
12627        if (dumpAll || dumpPackage != null) {
12628            synchronized (mPidsSelfLocked) {
12629                boolean printed = false;
12630                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12631                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12632                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12633                        continue;
12634                    }
12635                    if (!printed) {
12636                        if (needSep) pw.println();
12637                        needSep = true;
12638                        pw.println("  PID mappings:");
12639                        printed = true;
12640                        printedAnything = true;
12641                    }
12642                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12643                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12644                }
12645            }
12646        }
12647
12648        if (mForegroundProcesses.size() > 0) {
12649            synchronized (mPidsSelfLocked) {
12650                boolean printed = false;
12651                for (int i=0; i<mForegroundProcesses.size(); i++) {
12652                    ProcessRecord r = mPidsSelfLocked.get(
12653                            mForegroundProcesses.valueAt(i).pid);
12654                    if (dumpPackage != null && (r == null
12655                            || !r.pkgList.containsKey(dumpPackage))) {
12656                        continue;
12657                    }
12658                    if (!printed) {
12659                        if (needSep) pw.println();
12660                        needSep = true;
12661                        pw.println("  Foreground Processes:");
12662                        printed = true;
12663                        printedAnything = true;
12664                    }
12665                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12666                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12667                }
12668            }
12669        }
12670
12671        if (mPersistentStartingProcesses.size() > 0) {
12672            if (needSep) pw.println();
12673            needSep = true;
12674            printedAnything = true;
12675            pw.println("  Persisent processes that are starting:");
12676            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12677                    "Starting Norm", "Restarting PERS", dumpPackage);
12678        }
12679
12680        if (mRemovedProcesses.size() > 0) {
12681            if (needSep) pw.println();
12682            needSep = true;
12683            printedAnything = true;
12684            pw.println("  Processes that are being removed:");
12685            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12686                    "Removed Norm", "Removed PERS", dumpPackage);
12687        }
12688
12689        if (mProcessesOnHold.size() > 0) {
12690            if (needSep) pw.println();
12691            needSep = true;
12692            printedAnything = true;
12693            pw.println("  Processes that are on old until the system is ready:");
12694            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12695                    "OnHold Norm", "OnHold PERS", dumpPackage);
12696        }
12697
12698        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12699
12700        if (mProcessCrashTimes.getMap().size() > 0) {
12701            boolean printed = false;
12702            long now = SystemClock.uptimeMillis();
12703            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12704            final int NP = pmap.size();
12705            for (int ip=0; ip<NP; ip++) {
12706                String pname = pmap.keyAt(ip);
12707                SparseArray<Long> uids = pmap.valueAt(ip);
12708                final int N = uids.size();
12709                for (int i=0; i<N; i++) {
12710                    int puid = uids.keyAt(i);
12711                    ProcessRecord r = mProcessNames.get(pname, puid);
12712                    if (dumpPackage != null && (r == null
12713                            || !r.pkgList.containsKey(dumpPackage))) {
12714                        continue;
12715                    }
12716                    if (!printed) {
12717                        if (needSep) pw.println();
12718                        needSep = true;
12719                        pw.println("  Time since processes crashed:");
12720                        printed = true;
12721                        printedAnything = true;
12722                    }
12723                    pw.print("    Process "); pw.print(pname);
12724                            pw.print(" uid "); pw.print(puid);
12725                            pw.print(": last crashed ");
12726                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12727                            pw.println(" ago");
12728                }
12729            }
12730        }
12731
12732        if (mBadProcesses.getMap().size() > 0) {
12733            boolean printed = false;
12734            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12735            final int NP = pmap.size();
12736            for (int ip=0; ip<NP; ip++) {
12737                String pname = pmap.keyAt(ip);
12738                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12739                final int N = uids.size();
12740                for (int i=0; i<N; i++) {
12741                    int puid = uids.keyAt(i);
12742                    ProcessRecord r = mProcessNames.get(pname, puid);
12743                    if (dumpPackage != null && (r == null
12744                            || !r.pkgList.containsKey(dumpPackage))) {
12745                        continue;
12746                    }
12747                    if (!printed) {
12748                        if (needSep) pw.println();
12749                        needSep = true;
12750                        pw.println("  Bad processes:");
12751                        printedAnything = true;
12752                    }
12753                    BadProcessInfo info = uids.valueAt(i);
12754                    pw.print("    Bad process "); pw.print(pname);
12755                            pw.print(" uid "); pw.print(puid);
12756                            pw.print(": crashed at time "); pw.println(info.time);
12757                    if (info.shortMsg != null) {
12758                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12759                    }
12760                    if (info.longMsg != null) {
12761                        pw.print("      Long msg: "); pw.println(info.longMsg);
12762                    }
12763                    if (info.stack != null) {
12764                        pw.println("      Stack:");
12765                        int lastPos = 0;
12766                        for (int pos=0; pos<info.stack.length(); pos++) {
12767                            if (info.stack.charAt(pos) == '\n') {
12768                                pw.print("        ");
12769                                pw.write(info.stack, lastPos, pos-lastPos);
12770                                pw.println();
12771                                lastPos = pos+1;
12772                            }
12773                        }
12774                        if (lastPos < info.stack.length()) {
12775                            pw.print("        ");
12776                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12777                            pw.println();
12778                        }
12779                    }
12780                }
12781            }
12782        }
12783
12784        if (dumpPackage == null) {
12785            pw.println();
12786            needSep = false;
12787            pw.println("  mStartedUsers:");
12788            for (int i=0; i<mStartedUsers.size(); i++) {
12789                UserStartedState uss = mStartedUsers.valueAt(i);
12790                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12791                        pw.print(": "); uss.dump("", pw);
12792            }
12793            pw.print("  mStartedUserArray: [");
12794            for (int i=0; i<mStartedUserArray.length; i++) {
12795                if (i > 0) pw.print(", ");
12796                pw.print(mStartedUserArray[i]);
12797            }
12798            pw.println("]");
12799            pw.print("  mUserLru: [");
12800            for (int i=0; i<mUserLru.size(); i++) {
12801                if (i > 0) pw.print(", ");
12802                pw.print(mUserLru.get(i));
12803            }
12804            pw.println("]");
12805            if (dumpAll) {
12806                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12807            }
12808            synchronized (mUserProfileGroupIdsSelfLocked) {
12809                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12810                    pw.println("  mUserProfileGroupIds:");
12811                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12812                        pw.print("    User #");
12813                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12814                        pw.print(" -> profile #");
12815                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12816                    }
12817                }
12818            }
12819        }
12820        if (mHomeProcess != null && (dumpPackage == null
12821                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12822            if (needSep) {
12823                pw.println();
12824                needSep = false;
12825            }
12826            pw.println("  mHomeProcess: " + mHomeProcess);
12827        }
12828        if (mPreviousProcess != null && (dumpPackage == null
12829                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12830            if (needSep) {
12831                pw.println();
12832                needSep = false;
12833            }
12834            pw.println("  mPreviousProcess: " + mPreviousProcess);
12835        }
12836        if (dumpAll) {
12837            StringBuilder sb = new StringBuilder(128);
12838            sb.append("  mPreviousProcessVisibleTime: ");
12839            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12840            pw.println(sb);
12841        }
12842        if (mHeavyWeightProcess != null && (dumpPackage == null
12843                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12844            if (needSep) {
12845                pw.println();
12846                needSep = false;
12847            }
12848            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12849        }
12850        if (dumpPackage == null) {
12851            pw.println("  mConfiguration: " + mConfiguration);
12852        }
12853        if (dumpAll) {
12854            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12855            if (mCompatModePackages.getPackages().size() > 0) {
12856                boolean printed = false;
12857                for (Map.Entry<String, Integer> entry
12858                        : mCompatModePackages.getPackages().entrySet()) {
12859                    String pkg = entry.getKey();
12860                    int mode = entry.getValue();
12861                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12862                        continue;
12863                    }
12864                    if (!printed) {
12865                        pw.println("  mScreenCompatPackages:");
12866                        printed = true;
12867                    }
12868                    pw.print("    "); pw.print(pkg); pw.print(": ");
12869                            pw.print(mode); pw.println();
12870                }
12871            }
12872        }
12873        if (dumpPackage == null) {
12874            if (mSleeping || mWentToSleep || mLockScreenShown) {
12875                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12876                        + " mLockScreenShown " + mLockScreenShown);
12877            }
12878            if (mShuttingDown || mRunningVoice) {
12879                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12880            }
12881        }
12882        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12883                || mOrigWaitForDebugger) {
12884            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12885                    || dumpPackage.equals(mOrigDebugApp)) {
12886                if (needSep) {
12887                    pw.println();
12888                    needSep = false;
12889                }
12890                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12891                        + " mDebugTransient=" + mDebugTransient
12892                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12893            }
12894        }
12895        if (mOpenGlTraceApp != null) {
12896            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12897                if (needSep) {
12898                    pw.println();
12899                    needSep = false;
12900                }
12901                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12902            }
12903        }
12904        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12905                || mProfileFd != null) {
12906            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12907                if (needSep) {
12908                    pw.println();
12909                    needSep = false;
12910                }
12911                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12912                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12913                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12914                        + mAutoStopProfiler);
12915                pw.println("  mProfileType=" + mProfileType);
12916            }
12917        }
12918        if (dumpPackage == null) {
12919            if (mAlwaysFinishActivities || mController != null) {
12920                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12921                        + " mController=" + mController);
12922            }
12923            if (dumpAll) {
12924                pw.println("  Total persistent processes: " + numPers);
12925                pw.println("  mProcessesReady=" + mProcessesReady
12926                        + " mSystemReady=" + mSystemReady
12927                        + " mBooted=" + mBooted
12928                        + " mFactoryTest=" + mFactoryTest);
12929                pw.println("  mBooting=" + mBooting
12930                        + " mCallFinishBooting=" + mCallFinishBooting
12931                        + " mBootAnimationComplete=" + mBootAnimationComplete);
12932                pw.print("  mLastPowerCheckRealtime=");
12933                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12934                        pw.println("");
12935                pw.print("  mLastPowerCheckUptime=");
12936                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12937                        pw.println("");
12938                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12939                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12940                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12941                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12942                        + " (" + mLruProcesses.size() + " total)"
12943                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12944                        + " mNumServiceProcs=" + mNumServiceProcs
12945                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12946                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12947                        + " mLastMemoryLevel" + mLastMemoryLevel
12948                        + " mLastNumProcesses" + mLastNumProcesses);
12949                long now = SystemClock.uptimeMillis();
12950                pw.print("  mLastIdleTime=");
12951                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12952                        pw.print(" mLowRamSinceLastIdle=");
12953                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12954                        pw.println();
12955            }
12956        }
12957
12958        if (!printedAnything) {
12959            pw.println("  (nothing)");
12960        }
12961    }
12962
12963    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12964            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12965        if (mProcessesToGc.size() > 0) {
12966            boolean printed = false;
12967            long now = SystemClock.uptimeMillis();
12968            for (int i=0; i<mProcessesToGc.size(); i++) {
12969                ProcessRecord proc = mProcessesToGc.get(i);
12970                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12971                    continue;
12972                }
12973                if (!printed) {
12974                    if (needSep) pw.println();
12975                    needSep = true;
12976                    pw.println("  Processes that are waiting to GC:");
12977                    printed = true;
12978                }
12979                pw.print("    Process "); pw.println(proc);
12980                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12981                        pw.print(", last gced=");
12982                        pw.print(now-proc.lastRequestedGc);
12983                        pw.print(" ms ago, last lowMem=");
12984                        pw.print(now-proc.lastLowMemory);
12985                        pw.println(" ms ago");
12986
12987            }
12988        }
12989        return needSep;
12990    }
12991
12992    void printOomLevel(PrintWriter pw, String name, int adj) {
12993        pw.print("    ");
12994        if (adj >= 0) {
12995            pw.print(' ');
12996            if (adj < 10) pw.print(' ');
12997        } else {
12998            if (adj > -10) pw.print(' ');
12999        }
13000        pw.print(adj);
13001        pw.print(": ");
13002        pw.print(name);
13003        pw.print(" (");
13004        pw.print(mProcessList.getMemLevel(adj)/1024);
13005        pw.println(" kB)");
13006    }
13007
13008    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13009            int opti, boolean dumpAll) {
13010        boolean needSep = false;
13011
13012        if (mLruProcesses.size() > 0) {
13013            if (needSep) pw.println();
13014            needSep = true;
13015            pw.println("  OOM levels:");
13016            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13017            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13018            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13019            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13020            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13021            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13022            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13023            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13024            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13025            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13026            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13027            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13028            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13029
13030            if (needSep) pw.println();
13031            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13032                    pw.print(" total, non-act at ");
13033                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13034                    pw.print(", non-svc at ");
13035                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13036                    pw.println("):");
13037            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13038            needSep = true;
13039        }
13040
13041        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13042
13043        pw.println();
13044        pw.println("  mHomeProcess: " + mHomeProcess);
13045        pw.println("  mPreviousProcess: " + mPreviousProcess);
13046        if (mHeavyWeightProcess != null) {
13047            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13048        }
13049
13050        return true;
13051    }
13052
13053    /**
13054     * There are three ways to call this:
13055     *  - no provider specified: dump all the providers
13056     *  - a flattened component name that matched an existing provider was specified as the
13057     *    first arg: dump that one provider
13058     *  - the first arg isn't the flattened component name of an existing provider:
13059     *    dump all providers whose component contains the first arg as a substring
13060     */
13061    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13062            int opti, boolean dumpAll) {
13063        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13064    }
13065
13066    static class ItemMatcher {
13067        ArrayList<ComponentName> components;
13068        ArrayList<String> strings;
13069        ArrayList<Integer> objects;
13070        boolean all;
13071
13072        ItemMatcher() {
13073            all = true;
13074        }
13075
13076        void build(String name) {
13077            ComponentName componentName = ComponentName.unflattenFromString(name);
13078            if (componentName != null) {
13079                if (components == null) {
13080                    components = new ArrayList<ComponentName>();
13081                }
13082                components.add(componentName);
13083                all = false;
13084            } else {
13085                int objectId = 0;
13086                // Not a '/' separated full component name; maybe an object ID?
13087                try {
13088                    objectId = Integer.parseInt(name, 16);
13089                    if (objects == null) {
13090                        objects = new ArrayList<Integer>();
13091                    }
13092                    objects.add(objectId);
13093                    all = false;
13094                } catch (RuntimeException e) {
13095                    // Not an integer; just do string match.
13096                    if (strings == null) {
13097                        strings = new ArrayList<String>();
13098                    }
13099                    strings.add(name);
13100                    all = false;
13101                }
13102            }
13103        }
13104
13105        int build(String[] args, int opti) {
13106            for (; opti<args.length; opti++) {
13107                String name = args[opti];
13108                if ("--".equals(name)) {
13109                    return opti+1;
13110                }
13111                build(name);
13112            }
13113            return opti;
13114        }
13115
13116        boolean match(Object object, ComponentName comp) {
13117            if (all) {
13118                return true;
13119            }
13120            if (components != null) {
13121                for (int i=0; i<components.size(); i++) {
13122                    if (components.get(i).equals(comp)) {
13123                        return true;
13124                    }
13125                }
13126            }
13127            if (objects != null) {
13128                for (int i=0; i<objects.size(); i++) {
13129                    if (System.identityHashCode(object) == objects.get(i)) {
13130                        return true;
13131                    }
13132                }
13133            }
13134            if (strings != null) {
13135                String flat = comp.flattenToString();
13136                for (int i=0; i<strings.size(); i++) {
13137                    if (flat.contains(strings.get(i))) {
13138                        return true;
13139                    }
13140                }
13141            }
13142            return false;
13143        }
13144    }
13145
13146    /**
13147     * There are three things that cmd can be:
13148     *  - a flattened component name that matches an existing activity
13149     *  - the cmd arg isn't the flattened component name of an existing activity:
13150     *    dump all activity whose component contains the cmd as a substring
13151     *  - A hex number of the ActivityRecord object instance.
13152     */
13153    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13154            int opti, boolean dumpAll) {
13155        ArrayList<ActivityRecord> activities;
13156
13157        synchronized (this) {
13158            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13159        }
13160
13161        if (activities.size() <= 0) {
13162            return false;
13163        }
13164
13165        String[] newArgs = new String[args.length - opti];
13166        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13167
13168        TaskRecord lastTask = null;
13169        boolean needSep = false;
13170        for (int i=activities.size()-1; i>=0; i--) {
13171            ActivityRecord r = activities.get(i);
13172            if (needSep) {
13173                pw.println();
13174            }
13175            needSep = true;
13176            synchronized (this) {
13177                if (lastTask != r.task) {
13178                    lastTask = r.task;
13179                    pw.print("TASK "); pw.print(lastTask.affinity);
13180                            pw.print(" id="); pw.println(lastTask.taskId);
13181                    if (dumpAll) {
13182                        lastTask.dump(pw, "  ");
13183                    }
13184                }
13185            }
13186            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13187        }
13188        return true;
13189    }
13190
13191    /**
13192     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13193     * there is a thread associated with the activity.
13194     */
13195    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13196            final ActivityRecord r, String[] args, boolean dumpAll) {
13197        String innerPrefix = prefix + "  ";
13198        synchronized (this) {
13199            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13200                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13201                    pw.print(" pid=");
13202                    if (r.app != null) pw.println(r.app.pid);
13203                    else pw.println("(not running)");
13204            if (dumpAll) {
13205                r.dump(pw, innerPrefix);
13206            }
13207        }
13208        if (r.app != null && r.app.thread != null) {
13209            // flush anything that is already in the PrintWriter since the thread is going
13210            // to write to the file descriptor directly
13211            pw.flush();
13212            try {
13213                TransferPipe tp = new TransferPipe();
13214                try {
13215                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13216                            r.appToken, innerPrefix, args);
13217                    tp.go(fd);
13218                } finally {
13219                    tp.kill();
13220                }
13221            } catch (IOException e) {
13222                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13223            } catch (RemoteException e) {
13224                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13225            }
13226        }
13227    }
13228
13229    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13230            int opti, boolean dumpAll, String dumpPackage) {
13231        boolean needSep = false;
13232        boolean onlyHistory = false;
13233        boolean printedAnything = false;
13234
13235        if ("history".equals(dumpPackage)) {
13236            if (opti < args.length && "-s".equals(args[opti])) {
13237                dumpAll = false;
13238            }
13239            onlyHistory = true;
13240            dumpPackage = null;
13241        }
13242
13243        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13244        if (!onlyHistory && dumpAll) {
13245            if (mRegisteredReceivers.size() > 0) {
13246                boolean printed = false;
13247                Iterator it = mRegisteredReceivers.values().iterator();
13248                while (it.hasNext()) {
13249                    ReceiverList r = (ReceiverList)it.next();
13250                    if (dumpPackage != null && (r.app == null ||
13251                            !dumpPackage.equals(r.app.info.packageName))) {
13252                        continue;
13253                    }
13254                    if (!printed) {
13255                        pw.println("  Registered Receivers:");
13256                        needSep = true;
13257                        printed = true;
13258                        printedAnything = true;
13259                    }
13260                    pw.print("  * "); pw.println(r);
13261                    r.dump(pw, "    ");
13262                }
13263            }
13264
13265            if (mReceiverResolver.dump(pw, needSep ?
13266                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13267                    "    ", dumpPackage, false)) {
13268                needSep = true;
13269                printedAnything = true;
13270            }
13271        }
13272
13273        for (BroadcastQueue q : mBroadcastQueues) {
13274            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13275            printedAnything |= needSep;
13276        }
13277
13278        needSep = true;
13279
13280        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13281            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13282                if (needSep) {
13283                    pw.println();
13284                }
13285                needSep = true;
13286                printedAnything = true;
13287                pw.print("  Sticky broadcasts for user ");
13288                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13289                StringBuilder sb = new StringBuilder(128);
13290                for (Map.Entry<String, ArrayList<Intent>> ent
13291                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13292                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13293                    if (dumpAll) {
13294                        pw.println(":");
13295                        ArrayList<Intent> intents = ent.getValue();
13296                        final int N = intents.size();
13297                        for (int i=0; i<N; i++) {
13298                            sb.setLength(0);
13299                            sb.append("    Intent: ");
13300                            intents.get(i).toShortString(sb, false, true, false, false);
13301                            pw.println(sb.toString());
13302                            Bundle bundle = intents.get(i).getExtras();
13303                            if (bundle != null) {
13304                                pw.print("      ");
13305                                pw.println(bundle.toString());
13306                            }
13307                        }
13308                    } else {
13309                        pw.println("");
13310                    }
13311                }
13312            }
13313        }
13314
13315        if (!onlyHistory && dumpAll) {
13316            pw.println();
13317            for (BroadcastQueue queue : mBroadcastQueues) {
13318                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13319                        + queue.mBroadcastsScheduled);
13320            }
13321            pw.println("  mHandler:");
13322            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13323            needSep = true;
13324            printedAnything = true;
13325        }
13326
13327        if (!printedAnything) {
13328            pw.println("  (nothing)");
13329        }
13330    }
13331
13332    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13333            int opti, boolean dumpAll, String dumpPackage) {
13334        boolean needSep;
13335        boolean printedAnything = false;
13336
13337        ItemMatcher matcher = new ItemMatcher();
13338        matcher.build(args, opti);
13339
13340        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13341
13342        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13343        printedAnything |= needSep;
13344
13345        if (mLaunchingProviders.size() > 0) {
13346            boolean printed = false;
13347            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13348                ContentProviderRecord r = mLaunchingProviders.get(i);
13349                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13350                    continue;
13351                }
13352                if (!printed) {
13353                    if (needSep) pw.println();
13354                    needSep = true;
13355                    pw.println("  Launching content providers:");
13356                    printed = true;
13357                    printedAnything = true;
13358                }
13359                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13360                        pw.println(r);
13361            }
13362        }
13363
13364        if (mGrantedUriPermissions.size() > 0) {
13365            boolean printed = false;
13366            int dumpUid = -2;
13367            if (dumpPackage != null) {
13368                try {
13369                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13370                } catch (NameNotFoundException e) {
13371                    dumpUid = -1;
13372                }
13373            }
13374            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13375                int uid = mGrantedUriPermissions.keyAt(i);
13376                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13377                    continue;
13378                }
13379                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13380                if (!printed) {
13381                    if (needSep) pw.println();
13382                    needSep = true;
13383                    pw.println("  Granted Uri Permissions:");
13384                    printed = true;
13385                    printedAnything = true;
13386                }
13387                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13388                for (UriPermission perm : perms.values()) {
13389                    pw.print("    "); pw.println(perm);
13390                    if (dumpAll) {
13391                        perm.dump(pw, "      ");
13392                    }
13393                }
13394            }
13395        }
13396
13397        if (!printedAnything) {
13398            pw.println("  (nothing)");
13399        }
13400    }
13401
13402    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13403            int opti, boolean dumpAll, String dumpPackage) {
13404        boolean printed = false;
13405
13406        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13407
13408        if (mIntentSenderRecords.size() > 0) {
13409            Iterator<WeakReference<PendingIntentRecord>> it
13410                    = mIntentSenderRecords.values().iterator();
13411            while (it.hasNext()) {
13412                WeakReference<PendingIntentRecord> ref = it.next();
13413                PendingIntentRecord rec = ref != null ? ref.get(): null;
13414                if (dumpPackage != null && (rec == null
13415                        || !dumpPackage.equals(rec.key.packageName))) {
13416                    continue;
13417                }
13418                printed = true;
13419                if (rec != null) {
13420                    pw.print("  * "); pw.println(rec);
13421                    if (dumpAll) {
13422                        rec.dump(pw, "    ");
13423                    }
13424                } else {
13425                    pw.print("  * "); pw.println(ref);
13426                }
13427            }
13428        }
13429
13430        if (!printed) {
13431            pw.println("  (nothing)");
13432        }
13433    }
13434
13435    private static final int dumpProcessList(PrintWriter pw,
13436            ActivityManagerService service, List list,
13437            String prefix, String normalLabel, String persistentLabel,
13438            String dumpPackage) {
13439        int numPers = 0;
13440        final int N = list.size()-1;
13441        for (int i=N; i>=0; i--) {
13442            ProcessRecord r = (ProcessRecord)list.get(i);
13443            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13444                continue;
13445            }
13446            pw.println(String.format("%s%s #%2d: %s",
13447                    prefix, (r.persistent ? persistentLabel : normalLabel),
13448                    i, r.toString()));
13449            if (r.persistent) {
13450                numPers++;
13451            }
13452        }
13453        return numPers;
13454    }
13455
13456    private static final boolean dumpProcessOomList(PrintWriter pw,
13457            ActivityManagerService service, List<ProcessRecord> origList,
13458            String prefix, String normalLabel, String persistentLabel,
13459            boolean inclDetails, String dumpPackage) {
13460
13461        ArrayList<Pair<ProcessRecord, Integer>> list
13462                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13463        for (int i=0; i<origList.size(); i++) {
13464            ProcessRecord r = origList.get(i);
13465            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13466                continue;
13467            }
13468            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13469        }
13470
13471        if (list.size() <= 0) {
13472            return false;
13473        }
13474
13475        Comparator<Pair<ProcessRecord, Integer>> comparator
13476                = new Comparator<Pair<ProcessRecord, Integer>>() {
13477            @Override
13478            public int compare(Pair<ProcessRecord, Integer> object1,
13479                    Pair<ProcessRecord, Integer> object2) {
13480                if (object1.first.setAdj != object2.first.setAdj) {
13481                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13482                }
13483                if (object1.second.intValue() != object2.second.intValue()) {
13484                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13485                }
13486                return 0;
13487            }
13488        };
13489
13490        Collections.sort(list, comparator);
13491
13492        final long curRealtime = SystemClock.elapsedRealtime();
13493        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13494        final long curUptime = SystemClock.uptimeMillis();
13495        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13496
13497        for (int i=list.size()-1; i>=0; i--) {
13498            ProcessRecord r = list.get(i).first;
13499            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13500            char schedGroup;
13501            switch (r.setSchedGroup) {
13502                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13503                    schedGroup = 'B';
13504                    break;
13505                case Process.THREAD_GROUP_DEFAULT:
13506                    schedGroup = 'F';
13507                    break;
13508                default:
13509                    schedGroup = '?';
13510                    break;
13511            }
13512            char foreground;
13513            if (r.foregroundActivities) {
13514                foreground = 'A';
13515            } else if (r.foregroundServices) {
13516                foreground = 'S';
13517            } else {
13518                foreground = ' ';
13519            }
13520            String procState = ProcessList.makeProcStateString(r.curProcState);
13521            pw.print(prefix);
13522            pw.print(r.persistent ? persistentLabel : normalLabel);
13523            pw.print(" #");
13524            int num = (origList.size()-1)-list.get(i).second;
13525            if (num < 10) pw.print(' ');
13526            pw.print(num);
13527            pw.print(": ");
13528            pw.print(oomAdj);
13529            pw.print(' ');
13530            pw.print(schedGroup);
13531            pw.print('/');
13532            pw.print(foreground);
13533            pw.print('/');
13534            pw.print(procState);
13535            pw.print(" trm:");
13536            if (r.trimMemoryLevel < 10) pw.print(' ');
13537            pw.print(r.trimMemoryLevel);
13538            pw.print(' ');
13539            pw.print(r.toShortString());
13540            pw.print(" (");
13541            pw.print(r.adjType);
13542            pw.println(')');
13543            if (r.adjSource != null || r.adjTarget != null) {
13544                pw.print(prefix);
13545                pw.print("    ");
13546                if (r.adjTarget instanceof ComponentName) {
13547                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13548                } else if (r.adjTarget != null) {
13549                    pw.print(r.adjTarget.toString());
13550                } else {
13551                    pw.print("{null}");
13552                }
13553                pw.print("<=");
13554                if (r.adjSource instanceof ProcessRecord) {
13555                    pw.print("Proc{");
13556                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13557                    pw.println("}");
13558                } else if (r.adjSource != null) {
13559                    pw.println(r.adjSource.toString());
13560                } else {
13561                    pw.println("{null}");
13562                }
13563            }
13564            if (inclDetails) {
13565                pw.print(prefix);
13566                pw.print("    ");
13567                pw.print("oom: max="); pw.print(r.maxAdj);
13568                pw.print(" curRaw="); pw.print(r.curRawAdj);
13569                pw.print(" setRaw="); pw.print(r.setRawAdj);
13570                pw.print(" cur="); pw.print(r.curAdj);
13571                pw.print(" set="); pw.println(r.setAdj);
13572                pw.print(prefix);
13573                pw.print("    ");
13574                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13575                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13576                pw.print(" lastPss="); pw.print(r.lastPss);
13577                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13578                pw.print(prefix);
13579                pw.print("    ");
13580                pw.print("cached="); pw.print(r.cached);
13581                pw.print(" empty="); pw.print(r.empty);
13582                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13583
13584                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13585                    if (r.lastWakeTime != 0) {
13586                        long wtime;
13587                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13588                        synchronized (stats) {
13589                            wtime = stats.getProcessWakeTime(r.info.uid,
13590                                    r.pid, curRealtime);
13591                        }
13592                        long timeUsed = wtime - r.lastWakeTime;
13593                        pw.print(prefix);
13594                        pw.print("    ");
13595                        pw.print("keep awake over ");
13596                        TimeUtils.formatDuration(realtimeSince, pw);
13597                        pw.print(" used ");
13598                        TimeUtils.formatDuration(timeUsed, pw);
13599                        pw.print(" (");
13600                        pw.print((timeUsed*100)/realtimeSince);
13601                        pw.println("%)");
13602                    }
13603                    if (r.lastCpuTime != 0) {
13604                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13605                        pw.print(prefix);
13606                        pw.print("    ");
13607                        pw.print("run cpu over ");
13608                        TimeUtils.formatDuration(uptimeSince, pw);
13609                        pw.print(" used ");
13610                        TimeUtils.formatDuration(timeUsed, pw);
13611                        pw.print(" (");
13612                        pw.print((timeUsed*100)/uptimeSince);
13613                        pw.println("%)");
13614                    }
13615                }
13616            }
13617        }
13618        return true;
13619    }
13620
13621    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13622        ArrayList<ProcessRecord> procs;
13623        synchronized (this) {
13624            if (args != null && args.length > start
13625                    && args[start].charAt(0) != '-') {
13626                procs = new ArrayList<ProcessRecord>();
13627                int pid = -1;
13628                try {
13629                    pid = Integer.parseInt(args[start]);
13630                } catch (NumberFormatException e) {
13631                }
13632                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13633                    ProcessRecord proc = mLruProcesses.get(i);
13634                    if (proc.pid == pid) {
13635                        procs.add(proc);
13636                    } else if (proc.processName.equals(args[start])) {
13637                        procs.add(proc);
13638                    }
13639                }
13640                if (procs.size() <= 0) {
13641                    return null;
13642                }
13643            } else {
13644                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13645            }
13646        }
13647        return procs;
13648    }
13649
13650    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13651            PrintWriter pw, String[] args) {
13652        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13653        if (procs == null) {
13654            pw.println("No process found for: " + args[0]);
13655            return;
13656        }
13657
13658        long uptime = SystemClock.uptimeMillis();
13659        long realtime = SystemClock.elapsedRealtime();
13660        pw.println("Applications Graphics Acceleration Info:");
13661        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13662
13663        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13664            ProcessRecord r = procs.get(i);
13665            if (r.thread != null) {
13666                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13667                pw.flush();
13668                try {
13669                    TransferPipe tp = new TransferPipe();
13670                    try {
13671                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13672                        tp.go(fd);
13673                    } finally {
13674                        tp.kill();
13675                    }
13676                } catch (IOException e) {
13677                    pw.println("Failure while dumping the app: " + r);
13678                    pw.flush();
13679                } catch (RemoteException e) {
13680                    pw.println("Got a RemoteException while dumping the app " + r);
13681                    pw.flush();
13682                }
13683            }
13684        }
13685    }
13686
13687    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13688        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13689        if (procs == null) {
13690            pw.println("No process found for: " + args[0]);
13691            return;
13692        }
13693
13694        pw.println("Applications Database Info:");
13695
13696        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13697            ProcessRecord r = procs.get(i);
13698            if (r.thread != null) {
13699                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13700                pw.flush();
13701                try {
13702                    TransferPipe tp = new TransferPipe();
13703                    try {
13704                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13705                        tp.go(fd);
13706                    } finally {
13707                        tp.kill();
13708                    }
13709                } catch (IOException e) {
13710                    pw.println("Failure while dumping the app: " + r);
13711                    pw.flush();
13712                } catch (RemoteException e) {
13713                    pw.println("Got a RemoteException while dumping the app " + r);
13714                    pw.flush();
13715                }
13716            }
13717        }
13718    }
13719
13720    final static class MemItem {
13721        final boolean isProc;
13722        final String label;
13723        final String shortLabel;
13724        final long pss;
13725        final int id;
13726        final boolean hasActivities;
13727        ArrayList<MemItem> subitems;
13728
13729        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13730                boolean _hasActivities) {
13731            isProc = true;
13732            label = _label;
13733            shortLabel = _shortLabel;
13734            pss = _pss;
13735            id = _id;
13736            hasActivities = _hasActivities;
13737        }
13738
13739        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13740            isProc = false;
13741            label = _label;
13742            shortLabel = _shortLabel;
13743            pss = _pss;
13744            id = _id;
13745            hasActivities = false;
13746        }
13747    }
13748
13749    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13750            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13751        if (sort && !isCompact) {
13752            Collections.sort(items, new Comparator<MemItem>() {
13753                @Override
13754                public int compare(MemItem lhs, MemItem rhs) {
13755                    if (lhs.pss < rhs.pss) {
13756                        return 1;
13757                    } else if (lhs.pss > rhs.pss) {
13758                        return -1;
13759                    }
13760                    return 0;
13761                }
13762            });
13763        }
13764
13765        for (int i=0; i<items.size(); i++) {
13766            MemItem mi = items.get(i);
13767            if (!isCompact) {
13768                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13769            } else if (mi.isProc) {
13770                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13771                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13772                pw.println(mi.hasActivities ? ",a" : ",e");
13773            } else {
13774                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13775                pw.println(mi.pss);
13776            }
13777            if (mi.subitems != null) {
13778                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13779                        true, isCompact);
13780            }
13781        }
13782    }
13783
13784    // These are in KB.
13785    static final long[] DUMP_MEM_BUCKETS = new long[] {
13786        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13787        120*1024, 160*1024, 200*1024,
13788        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13789        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13790    };
13791
13792    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13793            boolean stackLike) {
13794        int start = label.lastIndexOf('.');
13795        if (start >= 0) start++;
13796        else start = 0;
13797        int end = label.length();
13798        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13799            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13800                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13801                out.append(bucket);
13802                out.append(stackLike ? "MB." : "MB ");
13803                out.append(label, start, end);
13804                return;
13805            }
13806        }
13807        out.append(memKB/1024);
13808        out.append(stackLike ? "MB." : "MB ");
13809        out.append(label, start, end);
13810    }
13811
13812    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13813            ProcessList.NATIVE_ADJ,
13814            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13815            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13816            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13817            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13818            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13819    };
13820    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13821            "Native",
13822            "System", "Persistent", "Foreground",
13823            "Visible", "Perceptible",
13824            "Heavy Weight", "Backup",
13825            "A Services", "Home",
13826            "Previous", "B Services", "Cached"
13827    };
13828    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13829            "native",
13830            "sys", "pers", "fore",
13831            "vis", "percept",
13832            "heavy", "backup",
13833            "servicea", "home",
13834            "prev", "serviceb", "cached"
13835    };
13836
13837    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13838            long realtime, boolean isCheckinRequest, boolean isCompact) {
13839        if (isCheckinRequest || isCompact) {
13840            // short checkin version
13841            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13842        } else {
13843            pw.println("Applications Memory Usage (kB):");
13844            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13845        }
13846    }
13847
13848    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13849            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13850        boolean dumpDetails = false;
13851        boolean dumpFullDetails = false;
13852        boolean dumpDalvik = false;
13853        boolean oomOnly = false;
13854        boolean isCompact = false;
13855        boolean localOnly = false;
13856
13857        int opti = 0;
13858        while (opti < args.length) {
13859            String opt = args[opti];
13860            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13861                break;
13862            }
13863            opti++;
13864            if ("-a".equals(opt)) {
13865                dumpDetails = true;
13866                dumpFullDetails = true;
13867                dumpDalvik = true;
13868            } else if ("-d".equals(opt)) {
13869                dumpDalvik = true;
13870            } else if ("-c".equals(opt)) {
13871                isCompact = true;
13872            } else if ("--oom".equals(opt)) {
13873                oomOnly = true;
13874            } else if ("--local".equals(opt)) {
13875                localOnly = true;
13876            } else if ("-h".equals(opt)) {
13877                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13878                pw.println("  -a: include all available information for each process.");
13879                pw.println("  -d: include dalvik details when dumping process details.");
13880                pw.println("  -c: dump in a compact machine-parseable representation.");
13881                pw.println("  --oom: only show processes organized by oom adj.");
13882                pw.println("  --local: only collect details locally, don't call process.");
13883                pw.println("If [process] is specified it can be the name or ");
13884                pw.println("pid of a specific process to dump.");
13885                return;
13886            } else {
13887                pw.println("Unknown argument: " + opt + "; use -h for help");
13888            }
13889        }
13890
13891        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13892        long uptime = SystemClock.uptimeMillis();
13893        long realtime = SystemClock.elapsedRealtime();
13894        final long[] tmpLong = new long[1];
13895
13896        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13897        if (procs == null) {
13898            // No Java processes.  Maybe they want to print a native process.
13899            if (args != null && args.length > opti
13900                    && args[opti].charAt(0) != '-') {
13901                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13902                        = new ArrayList<ProcessCpuTracker.Stats>();
13903                updateCpuStatsNow();
13904                int findPid = -1;
13905                try {
13906                    findPid = Integer.parseInt(args[opti]);
13907                } catch (NumberFormatException e) {
13908                }
13909                synchronized (mProcessCpuTracker) {
13910                    final int N = mProcessCpuTracker.countStats();
13911                    for (int i=0; i<N; i++) {
13912                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13913                        if (st.pid == findPid || (st.baseName != null
13914                                && st.baseName.equals(args[opti]))) {
13915                            nativeProcs.add(st);
13916                        }
13917                    }
13918                }
13919                if (nativeProcs.size() > 0) {
13920                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13921                            isCompact);
13922                    Debug.MemoryInfo mi = null;
13923                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13924                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13925                        final int pid = r.pid;
13926                        if (!isCheckinRequest && dumpDetails) {
13927                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13928                        }
13929                        if (mi == null) {
13930                            mi = new Debug.MemoryInfo();
13931                        }
13932                        if (dumpDetails || (!brief && !oomOnly)) {
13933                            Debug.getMemoryInfo(pid, mi);
13934                        } else {
13935                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13936                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13937                        }
13938                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13939                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13940                        if (isCheckinRequest) {
13941                            pw.println();
13942                        }
13943                    }
13944                    return;
13945                }
13946            }
13947            pw.println("No process found for: " + args[opti]);
13948            return;
13949        }
13950
13951        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13952            dumpDetails = true;
13953        }
13954
13955        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13956
13957        String[] innerArgs = new String[args.length-opti];
13958        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13959
13960        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13961        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13962        long nativePss=0, dalvikPss=0, otherPss=0;
13963        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13964
13965        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13966        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13967                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13968
13969        long totalPss = 0;
13970        long cachedPss = 0;
13971
13972        Debug.MemoryInfo mi = null;
13973        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13974            final ProcessRecord r = procs.get(i);
13975            final IApplicationThread thread;
13976            final int pid;
13977            final int oomAdj;
13978            final boolean hasActivities;
13979            synchronized (this) {
13980                thread = r.thread;
13981                pid = r.pid;
13982                oomAdj = r.getSetAdjWithServices();
13983                hasActivities = r.activities.size() > 0;
13984            }
13985            if (thread != null) {
13986                if (!isCheckinRequest && dumpDetails) {
13987                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13988                }
13989                if (mi == null) {
13990                    mi = new Debug.MemoryInfo();
13991                }
13992                if (dumpDetails || (!brief && !oomOnly)) {
13993                    Debug.getMemoryInfo(pid, mi);
13994                } else {
13995                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13996                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13997                }
13998                if (dumpDetails) {
13999                    if (localOnly) {
14000                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14001                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14002                        if (isCheckinRequest) {
14003                            pw.println();
14004                        }
14005                    } else {
14006                        try {
14007                            pw.flush();
14008                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14009                                    dumpDalvik, innerArgs);
14010                        } catch (RemoteException e) {
14011                            if (!isCheckinRequest) {
14012                                pw.println("Got RemoteException!");
14013                                pw.flush();
14014                            }
14015                        }
14016                    }
14017                }
14018
14019                final long myTotalPss = mi.getTotalPss();
14020                final long myTotalUss = mi.getTotalUss();
14021
14022                synchronized (this) {
14023                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14024                        // Record this for posterity if the process has been stable.
14025                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14026                    }
14027                }
14028
14029                if (!isCheckinRequest && mi != null) {
14030                    totalPss += myTotalPss;
14031                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14032                            (hasActivities ? " / activities)" : ")"),
14033                            r.processName, myTotalPss, pid, hasActivities);
14034                    procMems.add(pssItem);
14035                    procMemsMap.put(pid, pssItem);
14036
14037                    nativePss += mi.nativePss;
14038                    dalvikPss += mi.dalvikPss;
14039                    otherPss += mi.otherPss;
14040                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14041                        long mem = mi.getOtherPss(j);
14042                        miscPss[j] += mem;
14043                        otherPss -= mem;
14044                    }
14045
14046                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14047                        cachedPss += myTotalPss;
14048                    }
14049
14050                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14051                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14052                                || oomIndex == (oomPss.length-1)) {
14053                            oomPss[oomIndex] += myTotalPss;
14054                            if (oomProcs[oomIndex] == null) {
14055                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14056                            }
14057                            oomProcs[oomIndex].add(pssItem);
14058                            break;
14059                        }
14060                    }
14061                }
14062            }
14063        }
14064
14065        long nativeProcTotalPss = 0;
14066
14067        if (!isCheckinRequest && procs.size() > 1) {
14068            // If we are showing aggregations, also look for native processes to
14069            // include so that our aggregations are more accurate.
14070            updateCpuStatsNow();
14071            synchronized (mProcessCpuTracker) {
14072                final int N = mProcessCpuTracker.countStats();
14073                for (int i=0; i<N; i++) {
14074                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14075                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14076                        if (mi == null) {
14077                            mi = new Debug.MemoryInfo();
14078                        }
14079                        if (!brief && !oomOnly) {
14080                            Debug.getMemoryInfo(st.pid, mi);
14081                        } else {
14082                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14083                            mi.nativePrivateDirty = (int)tmpLong[0];
14084                        }
14085
14086                        final long myTotalPss = mi.getTotalPss();
14087                        totalPss += myTotalPss;
14088                        nativeProcTotalPss += myTotalPss;
14089
14090                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14091                                st.name, myTotalPss, st.pid, false);
14092                        procMems.add(pssItem);
14093
14094                        nativePss += mi.nativePss;
14095                        dalvikPss += mi.dalvikPss;
14096                        otherPss += mi.otherPss;
14097                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14098                            long mem = mi.getOtherPss(j);
14099                            miscPss[j] += mem;
14100                            otherPss -= mem;
14101                        }
14102                        oomPss[0] += myTotalPss;
14103                        if (oomProcs[0] == null) {
14104                            oomProcs[0] = new ArrayList<MemItem>();
14105                        }
14106                        oomProcs[0].add(pssItem);
14107                    }
14108                }
14109            }
14110
14111            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14112
14113            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14114            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14115            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14116            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14117                String label = Debug.MemoryInfo.getOtherLabel(j);
14118                catMems.add(new MemItem(label, label, miscPss[j], j));
14119            }
14120
14121            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14122            for (int j=0; j<oomPss.length; j++) {
14123                if (oomPss[j] != 0) {
14124                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14125                            : DUMP_MEM_OOM_LABEL[j];
14126                    MemItem item = new MemItem(label, label, oomPss[j],
14127                            DUMP_MEM_OOM_ADJ[j]);
14128                    item.subitems = oomProcs[j];
14129                    oomMems.add(item);
14130                }
14131            }
14132
14133            if (!brief && !oomOnly && !isCompact) {
14134                pw.println();
14135                pw.println("Total PSS by process:");
14136                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14137                pw.println();
14138            }
14139            if (!isCompact) {
14140                pw.println("Total PSS by OOM adjustment:");
14141            }
14142            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14143            if (!brief && !oomOnly) {
14144                PrintWriter out = categoryPw != null ? categoryPw : pw;
14145                if (!isCompact) {
14146                    out.println();
14147                    out.println("Total PSS by category:");
14148                }
14149                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14150            }
14151            if (!isCompact) {
14152                pw.println();
14153            }
14154            MemInfoReader memInfo = new MemInfoReader();
14155            memInfo.readMemInfo();
14156            if (nativeProcTotalPss > 0) {
14157                synchronized (this) {
14158                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14159                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14160                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14161                            nativeProcTotalPss);
14162                }
14163            }
14164            if (!brief) {
14165                if (!isCompact) {
14166                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14167                    pw.print(" kB (status ");
14168                    switch (mLastMemoryLevel) {
14169                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14170                            pw.println("normal)");
14171                            break;
14172                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14173                            pw.println("moderate)");
14174                            break;
14175                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14176                            pw.println("low)");
14177                            break;
14178                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14179                            pw.println("critical)");
14180                            break;
14181                        default:
14182                            pw.print(mLastMemoryLevel);
14183                            pw.println(")");
14184                            break;
14185                    }
14186                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14187                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14188                            pw.print(cachedPss); pw.print(" cached pss + ");
14189                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14190                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14191                } else {
14192                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14193                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14194                            + memInfo.getFreeSizeKb()); pw.print(",");
14195                    pw.println(totalPss - cachedPss);
14196                }
14197            }
14198            if (!isCompact) {
14199                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14200                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14201                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14202                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14203                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14204                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14205                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14206                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14207                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14208                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14209                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14210            }
14211            if (!brief) {
14212                if (memInfo.getZramTotalSizeKb() != 0) {
14213                    if (!isCompact) {
14214                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14215                                pw.print(" kB physical used for ");
14216                                pw.print(memInfo.getSwapTotalSizeKb()
14217                                        - memInfo.getSwapFreeSizeKb());
14218                                pw.print(" kB in swap (");
14219                                pw.print(memInfo.getSwapTotalSizeKb());
14220                                pw.println(" kB total swap)");
14221                    } else {
14222                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14223                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14224                                pw.println(memInfo.getSwapFreeSizeKb());
14225                    }
14226                }
14227                final int[] SINGLE_LONG_FORMAT = new int[] {
14228                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14229                };
14230                long[] longOut = new long[1];
14231                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14232                        SINGLE_LONG_FORMAT, null, longOut, null);
14233                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14234                longOut[0] = 0;
14235                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14236                        SINGLE_LONG_FORMAT, null, longOut, null);
14237                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14238                longOut[0] = 0;
14239                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14240                        SINGLE_LONG_FORMAT, null, longOut, null);
14241                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14242                longOut[0] = 0;
14243                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14244                        SINGLE_LONG_FORMAT, null, longOut, null);
14245                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14246                if (!isCompact) {
14247                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14248                        pw.print("      KSM: "); pw.print(sharing);
14249                                pw.print(" kB saved from shared ");
14250                                pw.print(shared); pw.println(" kB");
14251                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14252                                pw.print(voltile); pw.println(" kB volatile");
14253                    }
14254                    pw.print("   Tuning: ");
14255                    pw.print(ActivityManager.staticGetMemoryClass());
14256                    pw.print(" (large ");
14257                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14258                    pw.print("), oom ");
14259                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14260                    pw.print(" kB");
14261                    pw.print(", restore limit ");
14262                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14263                    pw.print(" kB");
14264                    if (ActivityManager.isLowRamDeviceStatic()) {
14265                        pw.print(" (low-ram)");
14266                    }
14267                    if (ActivityManager.isHighEndGfx()) {
14268                        pw.print(" (high-end-gfx)");
14269                    }
14270                    pw.println();
14271                } else {
14272                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14273                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14274                    pw.println(voltile);
14275                    pw.print("tuning,");
14276                    pw.print(ActivityManager.staticGetMemoryClass());
14277                    pw.print(',');
14278                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14279                    pw.print(',');
14280                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14281                    if (ActivityManager.isLowRamDeviceStatic()) {
14282                        pw.print(",low-ram");
14283                    }
14284                    if (ActivityManager.isHighEndGfx()) {
14285                        pw.print(",high-end-gfx");
14286                    }
14287                    pw.println();
14288                }
14289            }
14290        }
14291    }
14292
14293    /**
14294     * Searches array of arguments for the specified string
14295     * @param args array of argument strings
14296     * @param value value to search for
14297     * @return true if the value is contained in the array
14298     */
14299    private static boolean scanArgs(String[] args, String value) {
14300        if (args != null) {
14301            for (String arg : args) {
14302                if (value.equals(arg)) {
14303                    return true;
14304                }
14305            }
14306        }
14307        return false;
14308    }
14309
14310    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14311            ContentProviderRecord cpr, boolean always) {
14312        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14313
14314        if (!inLaunching || always) {
14315            synchronized (cpr) {
14316                cpr.launchingApp = null;
14317                cpr.notifyAll();
14318            }
14319            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14320            String names[] = cpr.info.authority.split(";");
14321            for (int j = 0; j < names.length; j++) {
14322                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14323            }
14324        }
14325
14326        for (int i=0; i<cpr.connections.size(); i++) {
14327            ContentProviderConnection conn = cpr.connections.get(i);
14328            if (conn.waiting) {
14329                // If this connection is waiting for the provider, then we don't
14330                // need to mess with its process unless we are always removing
14331                // or for some reason the provider is not currently launching.
14332                if (inLaunching && !always) {
14333                    continue;
14334                }
14335            }
14336            ProcessRecord capp = conn.client;
14337            conn.dead = true;
14338            if (conn.stableCount > 0) {
14339                if (!capp.persistent && capp.thread != null
14340                        && capp.pid != 0
14341                        && capp.pid != MY_PID) {
14342                    capp.kill("depends on provider "
14343                            + cpr.name.flattenToShortString()
14344                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14345                }
14346            } else if (capp.thread != null && conn.provider.provider != null) {
14347                try {
14348                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14349                } catch (RemoteException e) {
14350                }
14351                // In the protocol here, we don't expect the client to correctly
14352                // clean up this connection, we'll just remove it.
14353                cpr.connections.remove(i);
14354                conn.client.conProviders.remove(conn);
14355            }
14356        }
14357
14358        if (inLaunching && always) {
14359            mLaunchingProviders.remove(cpr);
14360        }
14361        return inLaunching;
14362    }
14363
14364    /**
14365     * Main code for cleaning up a process when it has gone away.  This is
14366     * called both as a result of the process dying, or directly when stopping
14367     * a process when running in single process mode.
14368     *
14369     * @return Returns true if the given process has been restarted, so the
14370     * app that was passed in must remain on the process lists.
14371     */
14372    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14373            boolean restarting, boolean allowRestart, int index) {
14374        if (index >= 0) {
14375            removeLruProcessLocked(app);
14376            ProcessList.remove(app.pid);
14377        }
14378
14379        mProcessesToGc.remove(app);
14380        mPendingPssProcesses.remove(app);
14381
14382        // Dismiss any open dialogs.
14383        if (app.crashDialog != null && !app.forceCrashReport) {
14384            app.crashDialog.dismiss();
14385            app.crashDialog = null;
14386        }
14387        if (app.anrDialog != null) {
14388            app.anrDialog.dismiss();
14389            app.anrDialog = null;
14390        }
14391        if (app.waitDialog != null) {
14392            app.waitDialog.dismiss();
14393            app.waitDialog = null;
14394        }
14395
14396        app.crashing = false;
14397        app.notResponding = false;
14398
14399        app.resetPackageList(mProcessStats);
14400        app.unlinkDeathRecipient();
14401        app.makeInactive(mProcessStats);
14402        app.waitingToKill = null;
14403        app.forcingToForeground = null;
14404        updateProcessForegroundLocked(app, false, false);
14405        app.foregroundActivities = false;
14406        app.hasShownUi = false;
14407        app.treatLikeActivity = false;
14408        app.hasAboveClient = false;
14409        app.hasClientActivities = false;
14410
14411        mServices.killServicesLocked(app, allowRestart);
14412
14413        boolean restart = false;
14414
14415        // Remove published content providers.
14416        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14417            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14418            final boolean always = app.bad || !allowRestart;
14419            if (removeDyingProviderLocked(app, cpr, always) || always) {
14420                // We left the provider in the launching list, need to
14421                // restart it.
14422                restart = true;
14423            }
14424
14425            cpr.provider = null;
14426            cpr.proc = null;
14427        }
14428        app.pubProviders.clear();
14429
14430        // Take care of any launching providers waiting for this process.
14431        if (checkAppInLaunchingProvidersLocked(app, false)) {
14432            restart = true;
14433        }
14434
14435        // Unregister from connected content providers.
14436        if (!app.conProviders.isEmpty()) {
14437            for (int i=0; i<app.conProviders.size(); i++) {
14438                ContentProviderConnection conn = app.conProviders.get(i);
14439                conn.provider.connections.remove(conn);
14440            }
14441            app.conProviders.clear();
14442        }
14443
14444        // At this point there may be remaining entries in mLaunchingProviders
14445        // where we were the only one waiting, so they are no longer of use.
14446        // Look for these and clean up if found.
14447        // XXX Commented out for now.  Trying to figure out a way to reproduce
14448        // the actual situation to identify what is actually going on.
14449        if (false) {
14450            for (int i=0; i<mLaunchingProviders.size(); i++) {
14451                ContentProviderRecord cpr = (ContentProviderRecord)
14452                        mLaunchingProviders.get(i);
14453                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14454                    synchronized (cpr) {
14455                        cpr.launchingApp = null;
14456                        cpr.notifyAll();
14457                    }
14458                }
14459            }
14460        }
14461
14462        skipCurrentReceiverLocked(app);
14463
14464        // Unregister any receivers.
14465        for (int i=app.receivers.size()-1; i>=0; i--) {
14466            removeReceiverLocked(app.receivers.valueAt(i));
14467        }
14468        app.receivers.clear();
14469
14470        // If the app is undergoing backup, tell the backup manager about it
14471        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14472            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14473                    + mBackupTarget.appInfo + " died during backup");
14474            try {
14475                IBackupManager bm = IBackupManager.Stub.asInterface(
14476                        ServiceManager.getService(Context.BACKUP_SERVICE));
14477                bm.agentDisconnected(app.info.packageName);
14478            } catch (RemoteException e) {
14479                // can't happen; backup manager is local
14480            }
14481        }
14482
14483        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14484            ProcessChangeItem item = mPendingProcessChanges.get(i);
14485            if (item.pid == app.pid) {
14486                mPendingProcessChanges.remove(i);
14487                mAvailProcessChanges.add(item);
14488            }
14489        }
14490        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14491
14492        // If the caller is restarting this app, then leave it in its
14493        // current lists and let the caller take care of it.
14494        if (restarting) {
14495            return false;
14496        }
14497
14498        if (!app.persistent || app.isolated) {
14499            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14500                    "Removing non-persistent process during cleanup: " + app);
14501            mProcessNames.remove(app.processName, app.uid);
14502            mIsolatedProcesses.remove(app.uid);
14503            if (mHeavyWeightProcess == app) {
14504                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14505                        mHeavyWeightProcess.userId, 0));
14506                mHeavyWeightProcess = null;
14507            }
14508        } else if (!app.removed) {
14509            // This app is persistent, so we need to keep its record around.
14510            // If it is not already on the pending app list, add it there
14511            // and start a new process for it.
14512            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14513                mPersistentStartingProcesses.add(app);
14514                restart = true;
14515            }
14516        }
14517        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14518                "Clean-up removing on hold: " + app);
14519        mProcessesOnHold.remove(app);
14520
14521        if (app == mHomeProcess) {
14522            mHomeProcess = null;
14523        }
14524        if (app == mPreviousProcess) {
14525            mPreviousProcess = null;
14526        }
14527
14528        if (restart && !app.isolated) {
14529            // We have components that still need to be running in the
14530            // process, so re-launch it.
14531            if (index < 0) {
14532                ProcessList.remove(app.pid);
14533            }
14534            mProcessNames.put(app.processName, app.uid, app);
14535            startProcessLocked(app, "restart", app.processName);
14536            return true;
14537        } else if (app.pid > 0 && app.pid != MY_PID) {
14538            // Goodbye!
14539            boolean removed;
14540            synchronized (mPidsSelfLocked) {
14541                mPidsSelfLocked.remove(app.pid);
14542                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14543            }
14544            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14545            if (app.isolated) {
14546                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14547            }
14548            app.setPid(0);
14549        }
14550        return false;
14551    }
14552
14553    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14554        // Look through the content providers we are waiting to have launched,
14555        // and if any run in this process then either schedule a restart of
14556        // the process or kill the client waiting for it if this process has
14557        // gone bad.
14558        int NL = mLaunchingProviders.size();
14559        boolean restart = false;
14560        for (int i=0; i<NL; i++) {
14561            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14562            if (cpr.launchingApp == app) {
14563                if (!alwaysBad && !app.bad) {
14564                    restart = true;
14565                } else {
14566                    removeDyingProviderLocked(app, cpr, true);
14567                    // cpr should have been removed from mLaunchingProviders
14568                    NL = mLaunchingProviders.size();
14569                    i--;
14570                }
14571            }
14572        }
14573        return restart;
14574    }
14575
14576    // =========================================================
14577    // SERVICES
14578    // =========================================================
14579
14580    @Override
14581    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14582            int flags) {
14583        enforceNotIsolatedCaller("getServices");
14584        synchronized (this) {
14585            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14586        }
14587    }
14588
14589    @Override
14590    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14591        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14592        synchronized (this) {
14593            return mServices.getRunningServiceControlPanelLocked(name);
14594        }
14595    }
14596
14597    @Override
14598    public ComponentName startService(IApplicationThread caller, Intent service,
14599            String resolvedType, int userId) {
14600        enforceNotIsolatedCaller("startService");
14601        // Refuse possible leaked file descriptors
14602        if (service != null && service.hasFileDescriptors() == true) {
14603            throw new IllegalArgumentException("File descriptors passed in Intent");
14604        }
14605
14606        if (DEBUG_SERVICE)
14607            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14608        synchronized(this) {
14609            final int callingPid = Binder.getCallingPid();
14610            final int callingUid = Binder.getCallingUid();
14611            final long origId = Binder.clearCallingIdentity();
14612            ComponentName res = mServices.startServiceLocked(caller, service,
14613                    resolvedType, callingPid, callingUid, userId);
14614            Binder.restoreCallingIdentity(origId);
14615            return res;
14616        }
14617    }
14618
14619    ComponentName startServiceInPackage(int uid,
14620            Intent service, String resolvedType, int userId) {
14621        synchronized(this) {
14622            if (DEBUG_SERVICE)
14623                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14624            final long origId = Binder.clearCallingIdentity();
14625            ComponentName res = mServices.startServiceLocked(null, service,
14626                    resolvedType, -1, uid, userId);
14627            Binder.restoreCallingIdentity(origId);
14628            return res;
14629        }
14630    }
14631
14632    @Override
14633    public int stopService(IApplicationThread caller, Intent service,
14634            String resolvedType, int userId) {
14635        enforceNotIsolatedCaller("stopService");
14636        // Refuse possible leaked file descriptors
14637        if (service != null && service.hasFileDescriptors() == true) {
14638            throw new IllegalArgumentException("File descriptors passed in Intent");
14639        }
14640
14641        synchronized(this) {
14642            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14643        }
14644    }
14645
14646    @Override
14647    public IBinder peekService(Intent service, String resolvedType) {
14648        enforceNotIsolatedCaller("peekService");
14649        // Refuse possible leaked file descriptors
14650        if (service != null && service.hasFileDescriptors() == true) {
14651            throw new IllegalArgumentException("File descriptors passed in Intent");
14652        }
14653        synchronized(this) {
14654            return mServices.peekServiceLocked(service, resolvedType);
14655        }
14656    }
14657
14658    @Override
14659    public boolean stopServiceToken(ComponentName className, IBinder token,
14660            int startId) {
14661        synchronized(this) {
14662            return mServices.stopServiceTokenLocked(className, token, startId);
14663        }
14664    }
14665
14666    @Override
14667    public void setServiceForeground(ComponentName className, IBinder token,
14668            int id, Notification notification, boolean removeNotification) {
14669        synchronized(this) {
14670            mServices.setServiceForegroundLocked(className, token, id, notification,
14671                    removeNotification);
14672        }
14673    }
14674
14675    @Override
14676    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14677            boolean requireFull, String name, String callerPackage) {
14678        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14679                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14680    }
14681
14682    int unsafeConvertIncomingUser(int userId) {
14683        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14684                ? mCurrentUserId : userId;
14685    }
14686
14687    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14688            int allowMode, String name, String callerPackage) {
14689        final int callingUserId = UserHandle.getUserId(callingUid);
14690        if (callingUserId == userId) {
14691            return userId;
14692        }
14693
14694        // Note that we may be accessing mCurrentUserId outside of a lock...
14695        // shouldn't be a big deal, if this is being called outside
14696        // of a locked context there is intrinsically a race with
14697        // the value the caller will receive and someone else changing it.
14698        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14699        // we will switch to the calling user if access to the current user fails.
14700        int targetUserId = unsafeConvertIncomingUser(userId);
14701
14702        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14703            final boolean allow;
14704            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14705                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14706                // If the caller has this permission, they always pass go.  And collect $200.
14707                allow = true;
14708            } else if (allowMode == ALLOW_FULL_ONLY) {
14709                // We require full access, sucks to be you.
14710                allow = false;
14711            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14712                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14713                // If the caller does not have either permission, they are always doomed.
14714                allow = false;
14715            } else if (allowMode == ALLOW_NON_FULL) {
14716                // We are blanket allowing non-full access, you lucky caller!
14717                allow = true;
14718            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14719                // We may or may not allow this depending on whether the two users are
14720                // in the same profile.
14721                synchronized (mUserProfileGroupIdsSelfLocked) {
14722                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14723                            UserInfo.NO_PROFILE_GROUP_ID);
14724                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14725                            UserInfo.NO_PROFILE_GROUP_ID);
14726                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14727                            && callingProfile == targetProfile;
14728                }
14729            } else {
14730                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14731            }
14732            if (!allow) {
14733                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14734                    // In this case, they would like to just execute as their
14735                    // owner user instead of failing.
14736                    targetUserId = callingUserId;
14737                } else {
14738                    StringBuilder builder = new StringBuilder(128);
14739                    builder.append("Permission Denial: ");
14740                    builder.append(name);
14741                    if (callerPackage != null) {
14742                        builder.append(" from ");
14743                        builder.append(callerPackage);
14744                    }
14745                    builder.append(" asks to run as user ");
14746                    builder.append(userId);
14747                    builder.append(" but is calling from user ");
14748                    builder.append(UserHandle.getUserId(callingUid));
14749                    builder.append("; this requires ");
14750                    builder.append(INTERACT_ACROSS_USERS_FULL);
14751                    if (allowMode != ALLOW_FULL_ONLY) {
14752                        builder.append(" or ");
14753                        builder.append(INTERACT_ACROSS_USERS);
14754                    }
14755                    String msg = builder.toString();
14756                    Slog.w(TAG, msg);
14757                    throw new SecurityException(msg);
14758                }
14759            }
14760        }
14761        if (!allowAll && targetUserId < 0) {
14762            throw new IllegalArgumentException(
14763                    "Call does not support special user #" + targetUserId);
14764        }
14765        // Check shell permission
14766        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14767            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14768                    targetUserId)) {
14769                throw new SecurityException("Shell does not have permission to access user "
14770                        + targetUserId + "\n " + Debug.getCallers(3));
14771            }
14772        }
14773        return targetUserId;
14774    }
14775
14776    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14777            String className, int flags) {
14778        boolean result = false;
14779        // For apps that don't have pre-defined UIDs, check for permission
14780        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14781            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14782                if (ActivityManager.checkUidPermission(
14783                        INTERACT_ACROSS_USERS,
14784                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14785                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14786                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14787                            + " requests FLAG_SINGLE_USER, but app does not hold "
14788                            + INTERACT_ACROSS_USERS;
14789                    Slog.w(TAG, msg);
14790                    throw new SecurityException(msg);
14791                }
14792                // Permission passed
14793                result = true;
14794            }
14795        } else if ("system".equals(componentProcessName)) {
14796            result = true;
14797        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14798            // Phone app and persistent apps are allowed to export singleuser providers.
14799            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14800                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14801        }
14802        if (DEBUG_MU) {
14803            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14804                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14805        }
14806        return result;
14807    }
14808
14809    /**
14810     * Checks to see if the caller is in the same app as the singleton
14811     * component, or the component is in a special app. It allows special apps
14812     * to export singleton components but prevents exporting singleton
14813     * components for regular apps.
14814     */
14815    boolean isValidSingletonCall(int callingUid, int componentUid) {
14816        int componentAppId = UserHandle.getAppId(componentUid);
14817        return UserHandle.isSameApp(callingUid, componentUid)
14818                || componentAppId == Process.SYSTEM_UID
14819                || componentAppId == Process.PHONE_UID
14820                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14821                        == PackageManager.PERMISSION_GRANTED;
14822    }
14823
14824    public int bindService(IApplicationThread caller, IBinder token,
14825            Intent service, String resolvedType,
14826            IServiceConnection connection, int flags, int userId) {
14827        enforceNotIsolatedCaller("bindService");
14828
14829        // Refuse possible leaked file descriptors
14830        if (service != null && service.hasFileDescriptors() == true) {
14831            throw new IllegalArgumentException("File descriptors passed in Intent");
14832        }
14833
14834        synchronized(this) {
14835            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14836                    connection, flags, userId);
14837        }
14838    }
14839
14840    public boolean unbindService(IServiceConnection connection) {
14841        synchronized (this) {
14842            return mServices.unbindServiceLocked(connection);
14843        }
14844    }
14845
14846    public void publishService(IBinder token, Intent intent, IBinder service) {
14847        // Refuse possible leaked file descriptors
14848        if (intent != null && intent.hasFileDescriptors() == true) {
14849            throw new IllegalArgumentException("File descriptors passed in Intent");
14850        }
14851
14852        synchronized(this) {
14853            if (!(token instanceof ServiceRecord)) {
14854                throw new IllegalArgumentException("Invalid service token");
14855            }
14856            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14857        }
14858    }
14859
14860    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14861        // Refuse possible leaked file descriptors
14862        if (intent != null && intent.hasFileDescriptors() == true) {
14863            throw new IllegalArgumentException("File descriptors passed in Intent");
14864        }
14865
14866        synchronized(this) {
14867            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14868        }
14869    }
14870
14871    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14872        synchronized(this) {
14873            if (!(token instanceof ServiceRecord)) {
14874                throw new IllegalArgumentException("Invalid service token");
14875            }
14876            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14877        }
14878    }
14879
14880    // =========================================================
14881    // BACKUP AND RESTORE
14882    // =========================================================
14883
14884    // Cause the target app to be launched if necessary and its backup agent
14885    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14886    // activity manager to announce its creation.
14887    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14888        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14889        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14890
14891        synchronized(this) {
14892            // !!! TODO: currently no check here that we're already bound
14893            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14894            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14895            synchronized (stats) {
14896                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14897            }
14898
14899            // Backup agent is now in use, its package can't be stopped.
14900            try {
14901                AppGlobals.getPackageManager().setPackageStoppedState(
14902                        app.packageName, false, UserHandle.getUserId(app.uid));
14903            } catch (RemoteException e) {
14904            } catch (IllegalArgumentException e) {
14905                Slog.w(TAG, "Failed trying to unstop package "
14906                        + app.packageName + ": " + e);
14907            }
14908
14909            BackupRecord r = new BackupRecord(ss, app, backupMode);
14910            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14911                    ? new ComponentName(app.packageName, app.backupAgentName)
14912                    : new ComponentName("android", "FullBackupAgent");
14913            // startProcessLocked() returns existing proc's record if it's already running
14914            ProcessRecord proc = startProcessLocked(app.processName, app,
14915                    false, 0, "backup", hostingName, false, false, false);
14916            if (proc == null) {
14917                Slog.e(TAG, "Unable to start backup agent process " + r);
14918                return false;
14919            }
14920
14921            r.app = proc;
14922            mBackupTarget = r;
14923            mBackupAppName = app.packageName;
14924
14925            // Try not to kill the process during backup
14926            updateOomAdjLocked(proc);
14927
14928            // If the process is already attached, schedule the creation of the backup agent now.
14929            // If it is not yet live, this will be done when it attaches to the framework.
14930            if (proc.thread != null) {
14931                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14932                try {
14933                    proc.thread.scheduleCreateBackupAgent(app,
14934                            compatibilityInfoForPackageLocked(app), backupMode);
14935                } catch (RemoteException e) {
14936                    // Will time out on the backup manager side
14937                }
14938            } else {
14939                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14940            }
14941            // Invariants: at this point, the target app process exists and the application
14942            // is either already running or in the process of coming up.  mBackupTarget and
14943            // mBackupAppName describe the app, so that when it binds back to the AM we
14944            // know that it's scheduled for a backup-agent operation.
14945        }
14946
14947        return true;
14948    }
14949
14950    @Override
14951    public void clearPendingBackup() {
14952        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14953        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14954
14955        synchronized (this) {
14956            mBackupTarget = null;
14957            mBackupAppName = null;
14958        }
14959    }
14960
14961    // A backup agent has just come up
14962    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14963        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14964                + " = " + agent);
14965
14966        synchronized(this) {
14967            if (!agentPackageName.equals(mBackupAppName)) {
14968                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14969                return;
14970            }
14971        }
14972
14973        long oldIdent = Binder.clearCallingIdentity();
14974        try {
14975            IBackupManager bm = IBackupManager.Stub.asInterface(
14976                    ServiceManager.getService(Context.BACKUP_SERVICE));
14977            bm.agentConnected(agentPackageName, agent);
14978        } catch (RemoteException e) {
14979            // can't happen; the backup manager service is local
14980        } catch (Exception e) {
14981            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14982            e.printStackTrace();
14983        } finally {
14984            Binder.restoreCallingIdentity(oldIdent);
14985        }
14986    }
14987
14988    // done with this agent
14989    public void unbindBackupAgent(ApplicationInfo appInfo) {
14990        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14991        if (appInfo == null) {
14992            Slog.w(TAG, "unbind backup agent for null app");
14993            return;
14994        }
14995
14996        synchronized(this) {
14997            try {
14998                if (mBackupAppName == null) {
14999                    Slog.w(TAG, "Unbinding backup agent with no active backup");
15000                    return;
15001                }
15002
15003                if (!mBackupAppName.equals(appInfo.packageName)) {
15004                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15005                    return;
15006                }
15007
15008                // Not backing this app up any more; reset its OOM adjustment
15009                final ProcessRecord proc = mBackupTarget.app;
15010                updateOomAdjLocked(proc);
15011
15012                // If the app crashed during backup, 'thread' will be null here
15013                if (proc.thread != null) {
15014                    try {
15015                        proc.thread.scheduleDestroyBackupAgent(appInfo,
15016                                compatibilityInfoForPackageLocked(appInfo));
15017                    } catch (Exception e) {
15018                        Slog.e(TAG, "Exception when unbinding backup agent:");
15019                        e.printStackTrace();
15020                    }
15021                }
15022            } finally {
15023                mBackupTarget = null;
15024                mBackupAppName = null;
15025            }
15026        }
15027    }
15028    // =========================================================
15029    // BROADCASTS
15030    // =========================================================
15031
15032    private final List getStickiesLocked(String action, IntentFilter filter,
15033            List cur, int userId) {
15034        final ContentResolver resolver = mContext.getContentResolver();
15035        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15036        if (stickies == null) {
15037            return cur;
15038        }
15039        final ArrayList<Intent> list = stickies.get(action);
15040        if (list == null) {
15041            return cur;
15042        }
15043        int N = list.size();
15044        for (int i=0; i<N; i++) {
15045            Intent intent = list.get(i);
15046            if (filter.match(resolver, intent, true, TAG) >= 0) {
15047                if (cur == null) {
15048                    cur = new ArrayList<Intent>();
15049                }
15050                cur.add(intent);
15051            }
15052        }
15053        return cur;
15054    }
15055
15056    boolean isPendingBroadcastProcessLocked(int pid) {
15057        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15058                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15059    }
15060
15061    void skipPendingBroadcastLocked(int pid) {
15062            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15063            for (BroadcastQueue queue : mBroadcastQueues) {
15064                queue.skipPendingBroadcastLocked(pid);
15065            }
15066    }
15067
15068    // The app just attached; send any pending broadcasts that it should receive
15069    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15070        boolean didSomething = false;
15071        for (BroadcastQueue queue : mBroadcastQueues) {
15072            didSomething |= queue.sendPendingBroadcastsLocked(app);
15073        }
15074        return didSomething;
15075    }
15076
15077    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15078            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15079        enforceNotIsolatedCaller("registerReceiver");
15080        int callingUid;
15081        int callingPid;
15082        synchronized(this) {
15083            ProcessRecord callerApp = null;
15084            if (caller != null) {
15085                callerApp = getRecordForAppLocked(caller);
15086                if (callerApp == null) {
15087                    throw new SecurityException(
15088                            "Unable to find app for caller " + caller
15089                            + " (pid=" + Binder.getCallingPid()
15090                            + ") when registering receiver " + receiver);
15091                }
15092                if (callerApp.info.uid != Process.SYSTEM_UID &&
15093                        !callerApp.pkgList.containsKey(callerPackage) &&
15094                        !"android".equals(callerPackage)) {
15095                    throw new SecurityException("Given caller package " + callerPackage
15096                            + " is not running in process " + callerApp);
15097                }
15098                callingUid = callerApp.info.uid;
15099                callingPid = callerApp.pid;
15100            } else {
15101                callerPackage = null;
15102                callingUid = Binder.getCallingUid();
15103                callingPid = Binder.getCallingPid();
15104            }
15105
15106            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15107                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15108
15109            List allSticky = null;
15110
15111            // Look for any matching sticky broadcasts...
15112            Iterator actions = filter.actionsIterator();
15113            if (actions != null) {
15114                while (actions.hasNext()) {
15115                    String action = (String)actions.next();
15116                    allSticky = getStickiesLocked(action, filter, allSticky,
15117                            UserHandle.USER_ALL);
15118                    allSticky = getStickiesLocked(action, filter, allSticky,
15119                            UserHandle.getUserId(callingUid));
15120                }
15121            } else {
15122                allSticky = getStickiesLocked(null, filter, allSticky,
15123                        UserHandle.USER_ALL);
15124                allSticky = getStickiesLocked(null, filter, allSticky,
15125                        UserHandle.getUserId(callingUid));
15126            }
15127
15128            // The first sticky in the list is returned directly back to
15129            // the client.
15130            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15131
15132            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15133                    + ": " + sticky);
15134
15135            if (receiver == null) {
15136                return sticky;
15137            }
15138
15139            ReceiverList rl
15140                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15141            if (rl == null) {
15142                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15143                        userId, receiver);
15144                if (rl.app != null) {
15145                    rl.app.receivers.add(rl);
15146                } else {
15147                    try {
15148                        receiver.asBinder().linkToDeath(rl, 0);
15149                    } catch (RemoteException e) {
15150                        return sticky;
15151                    }
15152                    rl.linkedToDeath = true;
15153                }
15154                mRegisteredReceivers.put(receiver.asBinder(), rl);
15155            } else if (rl.uid != callingUid) {
15156                throw new IllegalArgumentException(
15157                        "Receiver requested to register for uid " + callingUid
15158                        + " was previously registered for uid " + rl.uid);
15159            } else if (rl.pid != callingPid) {
15160                throw new IllegalArgumentException(
15161                        "Receiver requested to register for pid " + callingPid
15162                        + " was previously registered for pid " + rl.pid);
15163            } else if (rl.userId != userId) {
15164                throw new IllegalArgumentException(
15165                        "Receiver requested to register for user " + userId
15166                        + " was previously registered for user " + rl.userId);
15167            }
15168            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15169                    permission, callingUid, userId);
15170            rl.add(bf);
15171            if (!bf.debugCheck()) {
15172                Slog.w(TAG, "==> For Dynamic broadast");
15173            }
15174            mReceiverResolver.addFilter(bf);
15175
15176            // Enqueue broadcasts for all existing stickies that match
15177            // this filter.
15178            if (allSticky != null) {
15179                ArrayList receivers = new ArrayList();
15180                receivers.add(bf);
15181
15182                int N = allSticky.size();
15183                for (int i=0; i<N; i++) {
15184                    Intent intent = (Intent)allSticky.get(i);
15185                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15186                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15187                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15188                            null, null, false, true, true, -1);
15189                    queue.enqueueParallelBroadcastLocked(r);
15190                    queue.scheduleBroadcastsLocked();
15191                }
15192            }
15193
15194            return sticky;
15195        }
15196    }
15197
15198    public void unregisterReceiver(IIntentReceiver receiver) {
15199        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15200
15201        final long origId = Binder.clearCallingIdentity();
15202        try {
15203            boolean doTrim = false;
15204
15205            synchronized(this) {
15206                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15207                if (rl != null) {
15208                    if (rl.curBroadcast != null) {
15209                        BroadcastRecord r = rl.curBroadcast;
15210                        final boolean doNext = finishReceiverLocked(
15211                                receiver.asBinder(), r.resultCode, r.resultData,
15212                                r.resultExtras, r.resultAbort);
15213                        if (doNext) {
15214                            doTrim = true;
15215                            r.queue.processNextBroadcast(false);
15216                        }
15217                    }
15218
15219                    if (rl.app != null) {
15220                        rl.app.receivers.remove(rl);
15221                    }
15222                    removeReceiverLocked(rl);
15223                    if (rl.linkedToDeath) {
15224                        rl.linkedToDeath = false;
15225                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15226                    }
15227                }
15228            }
15229
15230            // If we actually concluded any broadcasts, we might now be able
15231            // to trim the recipients' apps from our working set
15232            if (doTrim) {
15233                trimApplications();
15234                return;
15235            }
15236
15237        } finally {
15238            Binder.restoreCallingIdentity(origId);
15239        }
15240    }
15241
15242    void removeReceiverLocked(ReceiverList rl) {
15243        mRegisteredReceivers.remove(rl.receiver.asBinder());
15244        int N = rl.size();
15245        for (int i=0; i<N; i++) {
15246            mReceiverResolver.removeFilter(rl.get(i));
15247        }
15248    }
15249
15250    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15251        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15252            ProcessRecord r = mLruProcesses.get(i);
15253            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15254                try {
15255                    r.thread.dispatchPackageBroadcast(cmd, packages);
15256                } catch (RemoteException ex) {
15257                }
15258            }
15259        }
15260    }
15261
15262    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15263            int callingUid, int[] users) {
15264        List<ResolveInfo> receivers = null;
15265        try {
15266            HashSet<ComponentName> singleUserReceivers = null;
15267            boolean scannedFirstReceivers = false;
15268            for (int user : users) {
15269                // Skip users that have Shell restrictions
15270                if (callingUid == Process.SHELL_UID
15271                        && getUserManagerLocked().hasUserRestriction(
15272                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15273                    continue;
15274                }
15275                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15276                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15277                if (user != 0 && newReceivers != null) {
15278                    // If this is not the primary user, we need to check for
15279                    // any receivers that should be filtered out.
15280                    for (int i=0; i<newReceivers.size(); i++) {
15281                        ResolveInfo ri = newReceivers.get(i);
15282                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15283                            newReceivers.remove(i);
15284                            i--;
15285                        }
15286                    }
15287                }
15288                if (newReceivers != null && newReceivers.size() == 0) {
15289                    newReceivers = null;
15290                }
15291                if (receivers == null) {
15292                    receivers = newReceivers;
15293                } else if (newReceivers != null) {
15294                    // We need to concatenate the additional receivers
15295                    // found with what we have do far.  This would be easy,
15296                    // but we also need to de-dup any receivers that are
15297                    // singleUser.
15298                    if (!scannedFirstReceivers) {
15299                        // Collect any single user receivers we had already retrieved.
15300                        scannedFirstReceivers = true;
15301                        for (int i=0; i<receivers.size(); i++) {
15302                            ResolveInfo ri = receivers.get(i);
15303                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15304                                ComponentName cn = new ComponentName(
15305                                        ri.activityInfo.packageName, ri.activityInfo.name);
15306                                if (singleUserReceivers == null) {
15307                                    singleUserReceivers = new HashSet<ComponentName>();
15308                                }
15309                                singleUserReceivers.add(cn);
15310                            }
15311                        }
15312                    }
15313                    // Add the new results to the existing results, tracking
15314                    // and de-dupping single user receivers.
15315                    for (int i=0; i<newReceivers.size(); i++) {
15316                        ResolveInfo ri = newReceivers.get(i);
15317                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15318                            ComponentName cn = new ComponentName(
15319                                    ri.activityInfo.packageName, ri.activityInfo.name);
15320                            if (singleUserReceivers == null) {
15321                                singleUserReceivers = new HashSet<ComponentName>();
15322                            }
15323                            if (!singleUserReceivers.contains(cn)) {
15324                                singleUserReceivers.add(cn);
15325                                receivers.add(ri);
15326                            }
15327                        } else {
15328                            receivers.add(ri);
15329                        }
15330                    }
15331                }
15332            }
15333        } catch (RemoteException ex) {
15334            // pm is in same process, this will never happen.
15335        }
15336        return receivers;
15337    }
15338
15339    private final int broadcastIntentLocked(ProcessRecord callerApp,
15340            String callerPackage, Intent intent, String resolvedType,
15341            IIntentReceiver resultTo, int resultCode, String resultData,
15342            Bundle map, String requiredPermission, int appOp,
15343            boolean ordered, boolean sticky, int callingPid, int callingUid,
15344            int userId) {
15345        intent = new Intent(intent);
15346
15347        // By default broadcasts do not go to stopped apps.
15348        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15349
15350        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15351            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15352            + " ordered=" + ordered + " userid=" + userId);
15353        if ((resultTo != null) && !ordered) {
15354            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15355        }
15356
15357        userId = handleIncomingUser(callingPid, callingUid, userId,
15358                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15359
15360        // Make sure that the user who is receiving this broadcast is started.
15361        // If not, we will just skip it.
15362
15363        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15364            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15365                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15366                Slog.w(TAG, "Skipping broadcast of " + intent
15367                        + ": user " + userId + " is stopped");
15368                return ActivityManager.BROADCAST_SUCCESS;
15369            }
15370        }
15371
15372        /*
15373         * Prevent non-system code (defined here to be non-persistent
15374         * processes) from sending protected broadcasts.
15375         */
15376        int callingAppId = UserHandle.getAppId(callingUid);
15377        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15378            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15379            || callingAppId == Process.NFC_UID || callingUid == 0) {
15380            // Always okay.
15381        } else if (callerApp == null || !callerApp.persistent) {
15382            try {
15383                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15384                        intent.getAction())) {
15385                    String msg = "Permission Denial: not allowed to send broadcast "
15386                            + intent.getAction() + " from pid="
15387                            + callingPid + ", uid=" + callingUid;
15388                    Slog.w(TAG, msg);
15389                    throw new SecurityException(msg);
15390                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15391                    // Special case for compatibility: we don't want apps to send this,
15392                    // but historically it has not been protected and apps may be using it
15393                    // to poke their own app widget.  So, instead of making it protected,
15394                    // just limit it to the caller.
15395                    if (callerApp == null) {
15396                        String msg = "Permission Denial: not allowed to send broadcast "
15397                                + intent.getAction() + " from unknown caller.";
15398                        Slog.w(TAG, msg);
15399                        throw new SecurityException(msg);
15400                    } else if (intent.getComponent() != null) {
15401                        // They are good enough to send to an explicit component...  verify
15402                        // it is being sent to the calling app.
15403                        if (!intent.getComponent().getPackageName().equals(
15404                                callerApp.info.packageName)) {
15405                            String msg = "Permission Denial: not allowed to send broadcast "
15406                                    + intent.getAction() + " to "
15407                                    + intent.getComponent().getPackageName() + " from "
15408                                    + callerApp.info.packageName;
15409                            Slog.w(TAG, msg);
15410                            throw new SecurityException(msg);
15411                        }
15412                    } else {
15413                        // Limit broadcast to their own package.
15414                        intent.setPackage(callerApp.info.packageName);
15415                    }
15416                }
15417            } catch (RemoteException e) {
15418                Slog.w(TAG, "Remote exception", e);
15419                return ActivityManager.BROADCAST_SUCCESS;
15420            }
15421        }
15422
15423        // Handle special intents: if this broadcast is from the package
15424        // manager about a package being removed, we need to remove all of
15425        // its activities from the history stack.
15426        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15427                intent.getAction());
15428        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15429                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15430                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15431                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15432                || uidRemoved) {
15433            if (checkComponentPermission(
15434                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15435                    callingPid, callingUid, -1, true)
15436                    == PackageManager.PERMISSION_GRANTED) {
15437                if (uidRemoved) {
15438                    final Bundle intentExtras = intent.getExtras();
15439                    final int uid = intentExtras != null
15440                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15441                    if (uid >= 0) {
15442                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15443                        synchronized (bs) {
15444                            bs.removeUidStatsLocked(uid);
15445                        }
15446                        mAppOpsService.uidRemoved(uid);
15447                    }
15448                } else {
15449                    // If resources are unavailable just force stop all
15450                    // those packages and flush the attribute cache as well.
15451                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15452                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15453                        if (list != null && (list.length > 0)) {
15454                            for (String pkg : list) {
15455                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15456                                        "storage unmount");
15457                            }
15458                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15459                            sendPackageBroadcastLocked(
15460                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15461                        }
15462                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15463                            intent.getAction())) {
15464                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15465                    } else {
15466                        Uri data = intent.getData();
15467                        String ssp;
15468                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15469                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15470                                    intent.getAction());
15471                            boolean fullUninstall = removed &&
15472                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15473                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15474                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15475                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15476                                        false, fullUninstall, userId,
15477                                        removed ? "pkg removed" : "pkg changed");
15478                            }
15479                            if (removed) {
15480                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15481                                        new String[] {ssp}, userId);
15482                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15483                                    mAppOpsService.packageRemoved(
15484                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15485
15486                                    // Remove all permissions granted from/to this package
15487                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15488                                }
15489                            }
15490                        }
15491                    }
15492                }
15493            } else {
15494                String msg = "Permission Denial: " + intent.getAction()
15495                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15496                        + ", uid=" + callingUid + ")"
15497                        + " requires "
15498                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15499                Slog.w(TAG, msg);
15500                throw new SecurityException(msg);
15501            }
15502
15503        // Special case for adding a package: by default turn on compatibility
15504        // mode.
15505        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15506            Uri data = intent.getData();
15507            String ssp;
15508            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15509                mCompatModePackages.handlePackageAddedLocked(ssp,
15510                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15511            }
15512        }
15513
15514        /*
15515         * If this is the time zone changed action, queue up a message that will reset the timezone
15516         * of all currently running processes. This message will get queued up before the broadcast
15517         * happens.
15518         */
15519        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15520            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15521        }
15522
15523        /*
15524         * If the user set the time, let all running processes know.
15525         */
15526        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15527            final int is24Hour = intent.getBooleanExtra(
15528                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15529            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15530            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15531            synchronized (stats) {
15532                stats.noteCurrentTimeChangedLocked();
15533            }
15534        }
15535
15536        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15537            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15538        }
15539
15540        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15541            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15542            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15543        }
15544
15545        // Add to the sticky list if requested.
15546        if (sticky) {
15547            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15548                    callingPid, callingUid)
15549                    != PackageManager.PERMISSION_GRANTED) {
15550                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15551                        + callingPid + ", uid=" + callingUid
15552                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15553                Slog.w(TAG, msg);
15554                throw new SecurityException(msg);
15555            }
15556            if (requiredPermission != null) {
15557                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15558                        + " and enforce permission " + requiredPermission);
15559                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15560            }
15561            if (intent.getComponent() != null) {
15562                throw new SecurityException(
15563                        "Sticky broadcasts can't target a specific component");
15564            }
15565            // We use userId directly here, since the "all" target is maintained
15566            // as a separate set of sticky broadcasts.
15567            if (userId != UserHandle.USER_ALL) {
15568                // But first, if this is not a broadcast to all users, then
15569                // make sure it doesn't conflict with an existing broadcast to
15570                // all users.
15571                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15572                        UserHandle.USER_ALL);
15573                if (stickies != null) {
15574                    ArrayList<Intent> list = stickies.get(intent.getAction());
15575                    if (list != null) {
15576                        int N = list.size();
15577                        int i;
15578                        for (i=0; i<N; i++) {
15579                            if (intent.filterEquals(list.get(i))) {
15580                                throw new IllegalArgumentException(
15581                                        "Sticky broadcast " + intent + " for user "
15582                                        + userId + " conflicts with existing global broadcast");
15583                            }
15584                        }
15585                    }
15586                }
15587            }
15588            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15589            if (stickies == null) {
15590                stickies = new ArrayMap<String, ArrayList<Intent>>();
15591                mStickyBroadcasts.put(userId, stickies);
15592            }
15593            ArrayList<Intent> list = stickies.get(intent.getAction());
15594            if (list == null) {
15595                list = new ArrayList<Intent>();
15596                stickies.put(intent.getAction(), list);
15597            }
15598            int N = list.size();
15599            int i;
15600            for (i=0; i<N; i++) {
15601                if (intent.filterEquals(list.get(i))) {
15602                    // This sticky already exists, replace it.
15603                    list.set(i, new Intent(intent));
15604                    break;
15605                }
15606            }
15607            if (i >= N) {
15608                list.add(new Intent(intent));
15609            }
15610        }
15611
15612        int[] users;
15613        if (userId == UserHandle.USER_ALL) {
15614            // Caller wants broadcast to go to all started users.
15615            users = mStartedUserArray;
15616        } else {
15617            // Caller wants broadcast to go to one specific user.
15618            users = new int[] {userId};
15619        }
15620
15621        // Figure out who all will receive this broadcast.
15622        List receivers = null;
15623        List<BroadcastFilter> registeredReceivers = null;
15624        // Need to resolve the intent to interested receivers...
15625        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15626                 == 0) {
15627            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15628        }
15629        if (intent.getComponent() == null) {
15630            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15631                // Query one target user at a time, excluding shell-restricted users
15632                UserManagerService ums = getUserManagerLocked();
15633                for (int i = 0; i < users.length; i++) {
15634                    if (ums.hasUserRestriction(
15635                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15636                        continue;
15637                    }
15638                    List<BroadcastFilter> registeredReceiversForUser =
15639                            mReceiverResolver.queryIntent(intent,
15640                                    resolvedType, false, users[i]);
15641                    if (registeredReceivers == null) {
15642                        registeredReceivers = registeredReceiversForUser;
15643                    } else if (registeredReceiversForUser != null) {
15644                        registeredReceivers.addAll(registeredReceiversForUser);
15645                    }
15646                }
15647            } else {
15648                registeredReceivers = mReceiverResolver.queryIntent(intent,
15649                        resolvedType, false, userId);
15650            }
15651        }
15652
15653        final boolean replacePending =
15654                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15655
15656        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15657                + " replacePending=" + replacePending);
15658
15659        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15660        if (!ordered && NR > 0) {
15661            // If we are not serializing this broadcast, then send the
15662            // registered receivers separately so they don't wait for the
15663            // components to be launched.
15664            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15665            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15666                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15667                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15668                    ordered, sticky, false, userId);
15669            if (DEBUG_BROADCAST) Slog.v(
15670                    TAG, "Enqueueing parallel broadcast " + r);
15671            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15672            if (!replaced) {
15673                queue.enqueueParallelBroadcastLocked(r);
15674                queue.scheduleBroadcastsLocked();
15675            }
15676            registeredReceivers = null;
15677            NR = 0;
15678        }
15679
15680        // Merge into one list.
15681        int ir = 0;
15682        if (receivers != null) {
15683            // A special case for PACKAGE_ADDED: do not allow the package
15684            // being added to see this broadcast.  This prevents them from
15685            // using this as a back door to get run as soon as they are
15686            // installed.  Maybe in the future we want to have a special install
15687            // broadcast or such for apps, but we'd like to deliberately make
15688            // this decision.
15689            String skipPackages[] = null;
15690            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15691                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15692                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15693                Uri data = intent.getData();
15694                if (data != null) {
15695                    String pkgName = data.getSchemeSpecificPart();
15696                    if (pkgName != null) {
15697                        skipPackages = new String[] { pkgName };
15698                    }
15699                }
15700            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15701                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15702            }
15703            if (skipPackages != null && (skipPackages.length > 0)) {
15704                for (String skipPackage : skipPackages) {
15705                    if (skipPackage != null) {
15706                        int NT = receivers.size();
15707                        for (int it=0; it<NT; it++) {
15708                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15709                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15710                                receivers.remove(it);
15711                                it--;
15712                                NT--;
15713                            }
15714                        }
15715                    }
15716                }
15717            }
15718
15719            int NT = receivers != null ? receivers.size() : 0;
15720            int it = 0;
15721            ResolveInfo curt = null;
15722            BroadcastFilter curr = null;
15723            while (it < NT && ir < NR) {
15724                if (curt == null) {
15725                    curt = (ResolveInfo)receivers.get(it);
15726                }
15727                if (curr == null) {
15728                    curr = registeredReceivers.get(ir);
15729                }
15730                if (curr.getPriority() >= curt.priority) {
15731                    // Insert this broadcast record into the final list.
15732                    receivers.add(it, curr);
15733                    ir++;
15734                    curr = null;
15735                    it++;
15736                    NT++;
15737                } else {
15738                    // Skip to the next ResolveInfo in the final list.
15739                    it++;
15740                    curt = null;
15741                }
15742            }
15743        }
15744        while (ir < NR) {
15745            if (receivers == null) {
15746                receivers = new ArrayList();
15747            }
15748            receivers.add(registeredReceivers.get(ir));
15749            ir++;
15750        }
15751
15752        if ((receivers != null && receivers.size() > 0)
15753                || resultTo != null) {
15754            BroadcastQueue queue = broadcastQueueForIntent(intent);
15755            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15756                    callerPackage, callingPid, callingUid, resolvedType,
15757                    requiredPermission, appOp, receivers, resultTo, resultCode,
15758                    resultData, map, ordered, sticky, false, userId);
15759            if (DEBUG_BROADCAST) Slog.v(
15760                    TAG, "Enqueueing ordered broadcast " + r
15761                    + ": prev had " + queue.mOrderedBroadcasts.size());
15762            if (DEBUG_BROADCAST) {
15763                int seq = r.intent.getIntExtra("seq", -1);
15764                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15765            }
15766            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15767            if (!replaced) {
15768                queue.enqueueOrderedBroadcastLocked(r);
15769                queue.scheduleBroadcastsLocked();
15770            }
15771        }
15772
15773        return ActivityManager.BROADCAST_SUCCESS;
15774    }
15775
15776    final Intent verifyBroadcastLocked(Intent intent) {
15777        // Refuse possible leaked file descriptors
15778        if (intent != null && intent.hasFileDescriptors() == true) {
15779            throw new IllegalArgumentException("File descriptors passed in Intent");
15780        }
15781
15782        int flags = intent.getFlags();
15783
15784        if (!mProcessesReady) {
15785            // if the caller really truly claims to know what they're doing, go
15786            // ahead and allow the broadcast without launching any receivers
15787            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15788                intent = new Intent(intent);
15789                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15790            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15791                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15792                        + " before boot completion");
15793                throw new IllegalStateException("Cannot broadcast before boot completed");
15794            }
15795        }
15796
15797        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15798            throw new IllegalArgumentException(
15799                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15800        }
15801
15802        return intent;
15803    }
15804
15805    public final int broadcastIntent(IApplicationThread caller,
15806            Intent intent, String resolvedType, IIntentReceiver resultTo,
15807            int resultCode, String resultData, Bundle map,
15808            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15809        enforceNotIsolatedCaller("broadcastIntent");
15810        synchronized(this) {
15811            intent = verifyBroadcastLocked(intent);
15812
15813            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15814            final int callingPid = Binder.getCallingPid();
15815            final int callingUid = Binder.getCallingUid();
15816            final long origId = Binder.clearCallingIdentity();
15817            int res = broadcastIntentLocked(callerApp,
15818                    callerApp != null ? callerApp.info.packageName : null,
15819                    intent, resolvedType, resultTo,
15820                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15821                    callingPid, callingUid, userId);
15822            Binder.restoreCallingIdentity(origId);
15823            return res;
15824        }
15825    }
15826
15827    int broadcastIntentInPackage(String packageName, int uid,
15828            Intent intent, String resolvedType, IIntentReceiver resultTo,
15829            int resultCode, String resultData, Bundle map,
15830            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15831        synchronized(this) {
15832            intent = verifyBroadcastLocked(intent);
15833
15834            final long origId = Binder.clearCallingIdentity();
15835            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15836                    resultTo, resultCode, resultData, map, requiredPermission,
15837                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15838            Binder.restoreCallingIdentity(origId);
15839            return res;
15840        }
15841    }
15842
15843    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15844        // Refuse possible leaked file descriptors
15845        if (intent != null && intent.hasFileDescriptors() == true) {
15846            throw new IllegalArgumentException("File descriptors passed in Intent");
15847        }
15848
15849        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15850                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15851
15852        synchronized(this) {
15853            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15854                    != PackageManager.PERMISSION_GRANTED) {
15855                String msg = "Permission Denial: unbroadcastIntent() from pid="
15856                        + Binder.getCallingPid()
15857                        + ", uid=" + Binder.getCallingUid()
15858                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15859                Slog.w(TAG, msg);
15860                throw new SecurityException(msg);
15861            }
15862            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15863            if (stickies != null) {
15864                ArrayList<Intent> list = stickies.get(intent.getAction());
15865                if (list != null) {
15866                    int N = list.size();
15867                    int i;
15868                    for (i=0; i<N; i++) {
15869                        if (intent.filterEquals(list.get(i))) {
15870                            list.remove(i);
15871                            break;
15872                        }
15873                    }
15874                    if (list.size() <= 0) {
15875                        stickies.remove(intent.getAction());
15876                    }
15877                }
15878                if (stickies.size() <= 0) {
15879                    mStickyBroadcasts.remove(userId);
15880                }
15881            }
15882        }
15883    }
15884
15885    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15886            String resultData, Bundle resultExtras, boolean resultAbort) {
15887        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15888        if (r == null) {
15889            Slog.w(TAG, "finishReceiver called but not found on queue");
15890            return false;
15891        }
15892
15893        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15894    }
15895
15896    void backgroundServicesFinishedLocked(int userId) {
15897        for (BroadcastQueue queue : mBroadcastQueues) {
15898            queue.backgroundServicesFinishedLocked(userId);
15899        }
15900    }
15901
15902    public void finishReceiver(IBinder who, int resultCode, String resultData,
15903            Bundle resultExtras, boolean resultAbort) {
15904        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15905
15906        // Refuse possible leaked file descriptors
15907        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15908            throw new IllegalArgumentException("File descriptors passed in Bundle");
15909        }
15910
15911        final long origId = Binder.clearCallingIdentity();
15912        try {
15913            boolean doNext = false;
15914            BroadcastRecord r;
15915
15916            synchronized(this) {
15917                r = broadcastRecordForReceiverLocked(who);
15918                if (r != null) {
15919                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15920                        resultData, resultExtras, resultAbort, true);
15921                }
15922            }
15923
15924            if (doNext) {
15925                r.queue.processNextBroadcast(false);
15926            }
15927            trimApplications();
15928        } finally {
15929            Binder.restoreCallingIdentity(origId);
15930        }
15931    }
15932
15933    // =========================================================
15934    // INSTRUMENTATION
15935    // =========================================================
15936
15937    public boolean startInstrumentation(ComponentName className,
15938            String profileFile, int flags, Bundle arguments,
15939            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15940            int userId, String abiOverride) {
15941        enforceNotIsolatedCaller("startInstrumentation");
15942        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15943                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15944        // Refuse possible leaked file descriptors
15945        if (arguments != null && arguments.hasFileDescriptors()) {
15946            throw new IllegalArgumentException("File descriptors passed in Bundle");
15947        }
15948
15949        synchronized(this) {
15950            InstrumentationInfo ii = null;
15951            ApplicationInfo ai = null;
15952            try {
15953                ii = mContext.getPackageManager().getInstrumentationInfo(
15954                    className, STOCK_PM_FLAGS);
15955                ai = AppGlobals.getPackageManager().getApplicationInfo(
15956                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15957            } catch (PackageManager.NameNotFoundException e) {
15958            } catch (RemoteException e) {
15959            }
15960            if (ii == null) {
15961                reportStartInstrumentationFailure(watcher, className,
15962                        "Unable to find instrumentation info for: " + className);
15963                return false;
15964            }
15965            if (ai == null) {
15966                reportStartInstrumentationFailure(watcher, className,
15967                        "Unable to find instrumentation target package: " + ii.targetPackage);
15968                return false;
15969            }
15970
15971            int match = mContext.getPackageManager().checkSignatures(
15972                    ii.targetPackage, ii.packageName);
15973            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15974                String msg = "Permission Denial: starting instrumentation "
15975                        + className + " from pid="
15976                        + Binder.getCallingPid()
15977                        + ", uid=" + Binder.getCallingPid()
15978                        + " not allowed because package " + ii.packageName
15979                        + " does not have a signature matching the target "
15980                        + ii.targetPackage;
15981                reportStartInstrumentationFailure(watcher, className, msg);
15982                throw new SecurityException(msg);
15983            }
15984
15985            final long origId = Binder.clearCallingIdentity();
15986            // Instrumentation can kill and relaunch even persistent processes
15987            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15988                    "start instr");
15989            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15990            app.instrumentationClass = className;
15991            app.instrumentationInfo = ai;
15992            app.instrumentationProfileFile = profileFile;
15993            app.instrumentationArguments = arguments;
15994            app.instrumentationWatcher = watcher;
15995            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15996            app.instrumentationResultClass = className;
15997            Binder.restoreCallingIdentity(origId);
15998        }
15999
16000        return true;
16001    }
16002
16003    /**
16004     * Report errors that occur while attempting to start Instrumentation.  Always writes the
16005     * error to the logs, but if somebody is watching, send the report there too.  This enables
16006     * the "am" command to report errors with more information.
16007     *
16008     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
16009     * @param cn The component name of the instrumentation.
16010     * @param report The error report.
16011     */
16012    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16013            ComponentName cn, String report) {
16014        Slog.w(TAG, report);
16015        try {
16016            if (watcher != null) {
16017                Bundle results = new Bundle();
16018                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16019                results.putString("Error", report);
16020                watcher.instrumentationStatus(cn, -1, results);
16021            }
16022        } catch (RemoteException e) {
16023            Slog.w(TAG, e);
16024        }
16025    }
16026
16027    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16028        if (app.instrumentationWatcher != null) {
16029            try {
16030                // NOTE:  IInstrumentationWatcher *must* be oneway here
16031                app.instrumentationWatcher.instrumentationFinished(
16032                    app.instrumentationClass,
16033                    resultCode,
16034                    results);
16035            } catch (RemoteException e) {
16036            }
16037        }
16038        if (app.instrumentationUiAutomationConnection != null) {
16039            try {
16040                app.instrumentationUiAutomationConnection.shutdown();
16041            } catch (RemoteException re) {
16042                /* ignore */
16043            }
16044            // Only a UiAutomation can set this flag and now that
16045            // it is finished we make sure it is reset to its default.
16046            mUserIsMonkey = false;
16047        }
16048        app.instrumentationWatcher = null;
16049        app.instrumentationUiAutomationConnection = null;
16050        app.instrumentationClass = null;
16051        app.instrumentationInfo = null;
16052        app.instrumentationProfileFile = null;
16053        app.instrumentationArguments = null;
16054
16055        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16056                "finished inst");
16057    }
16058
16059    public void finishInstrumentation(IApplicationThread target,
16060            int resultCode, Bundle results) {
16061        int userId = UserHandle.getCallingUserId();
16062        // Refuse possible leaked file descriptors
16063        if (results != null && results.hasFileDescriptors()) {
16064            throw new IllegalArgumentException("File descriptors passed in Intent");
16065        }
16066
16067        synchronized(this) {
16068            ProcessRecord app = getRecordForAppLocked(target);
16069            if (app == null) {
16070                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16071                return;
16072            }
16073            final long origId = Binder.clearCallingIdentity();
16074            finishInstrumentationLocked(app, resultCode, results);
16075            Binder.restoreCallingIdentity(origId);
16076        }
16077    }
16078
16079    // =========================================================
16080    // CONFIGURATION
16081    // =========================================================
16082
16083    public ConfigurationInfo getDeviceConfigurationInfo() {
16084        ConfigurationInfo config = new ConfigurationInfo();
16085        synchronized (this) {
16086            config.reqTouchScreen = mConfiguration.touchscreen;
16087            config.reqKeyboardType = mConfiguration.keyboard;
16088            config.reqNavigation = mConfiguration.navigation;
16089            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16090                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16091                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16092            }
16093            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16094                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16095                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16096            }
16097            config.reqGlEsVersion = GL_ES_VERSION;
16098        }
16099        return config;
16100    }
16101
16102    ActivityStack getFocusedStack() {
16103        return mStackSupervisor.getFocusedStack();
16104    }
16105
16106    public Configuration getConfiguration() {
16107        Configuration ci;
16108        synchronized(this) {
16109            ci = new Configuration(mConfiguration);
16110        }
16111        return ci;
16112    }
16113
16114    public void updatePersistentConfiguration(Configuration values) {
16115        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16116                "updateConfiguration()");
16117        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16118                "updateConfiguration()");
16119        if (values == null) {
16120            throw new NullPointerException("Configuration must not be null");
16121        }
16122
16123        synchronized(this) {
16124            final long origId = Binder.clearCallingIdentity();
16125            updateConfigurationLocked(values, null, true, false);
16126            Binder.restoreCallingIdentity(origId);
16127        }
16128    }
16129
16130    public void updateConfiguration(Configuration values) {
16131        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16132                "updateConfiguration()");
16133
16134        synchronized(this) {
16135            if (values == null && mWindowManager != null) {
16136                // sentinel: fetch the current configuration from the window manager
16137                values = mWindowManager.computeNewConfiguration();
16138            }
16139
16140            if (mWindowManager != null) {
16141                mProcessList.applyDisplaySize(mWindowManager);
16142            }
16143
16144            final long origId = Binder.clearCallingIdentity();
16145            if (values != null) {
16146                Settings.System.clearConfiguration(values);
16147            }
16148            updateConfigurationLocked(values, null, false, false);
16149            Binder.restoreCallingIdentity(origId);
16150        }
16151    }
16152
16153    /**
16154     * Do either or both things: (1) change the current configuration, and (2)
16155     * make sure the given activity is running with the (now) current
16156     * configuration.  Returns true if the activity has been left running, or
16157     * false if <var>starting</var> is being destroyed to match the new
16158     * configuration.
16159     * @param persistent TODO
16160     */
16161    boolean updateConfigurationLocked(Configuration values,
16162            ActivityRecord starting, boolean persistent, boolean initLocale) {
16163        int changes = 0;
16164
16165        if (values != null) {
16166            Configuration newConfig = new Configuration(mConfiguration);
16167            changes = newConfig.updateFrom(values);
16168            if (changes != 0) {
16169                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16170                    Slog.i(TAG, "Updating configuration to: " + values);
16171                }
16172
16173                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16174
16175                if (values.locale != null && !initLocale) {
16176                    saveLocaleLocked(values.locale,
16177                                     !values.locale.equals(mConfiguration.locale),
16178                                     values.userSetLocale);
16179                }
16180
16181                mConfigurationSeq++;
16182                if (mConfigurationSeq <= 0) {
16183                    mConfigurationSeq = 1;
16184                }
16185                newConfig.seq = mConfigurationSeq;
16186                mConfiguration = newConfig;
16187                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16188                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16189                //mUsageStatsService.noteStartConfig(newConfig);
16190
16191                final Configuration configCopy = new Configuration(mConfiguration);
16192
16193                // TODO: If our config changes, should we auto dismiss any currently
16194                // showing dialogs?
16195                mShowDialogs = shouldShowDialogs(newConfig);
16196
16197                AttributeCache ac = AttributeCache.instance();
16198                if (ac != null) {
16199                    ac.updateConfiguration(configCopy);
16200                }
16201
16202                // Make sure all resources in our process are updated
16203                // right now, so that anyone who is going to retrieve
16204                // resource values after we return will be sure to get
16205                // the new ones.  This is especially important during
16206                // boot, where the first config change needs to guarantee
16207                // all resources have that config before following boot
16208                // code is executed.
16209                mSystemThread.applyConfigurationToResources(configCopy);
16210
16211                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16212                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16213                    msg.obj = new Configuration(configCopy);
16214                    mHandler.sendMessage(msg);
16215                }
16216
16217                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16218                    ProcessRecord app = mLruProcesses.get(i);
16219                    try {
16220                        if (app.thread != null) {
16221                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16222                                    + app.processName + " new config " + mConfiguration);
16223                            app.thread.scheduleConfigurationChanged(configCopy);
16224                        }
16225                    } catch (Exception e) {
16226                    }
16227                }
16228                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16229                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16230                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16231                        | Intent.FLAG_RECEIVER_FOREGROUND);
16232                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16233                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16234                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16235                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16236                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16237                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16238                    broadcastIntentLocked(null, null, intent,
16239                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16240                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16241                }
16242            }
16243        }
16244
16245        boolean kept = true;
16246        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16247        // mainStack is null during startup.
16248        if (mainStack != null) {
16249            if (changes != 0 && starting == null) {
16250                // If the configuration changed, and the caller is not already
16251                // in the process of starting an activity, then find the top
16252                // activity to check if its configuration needs to change.
16253                starting = mainStack.topRunningActivityLocked(null);
16254            }
16255
16256            if (starting != null) {
16257                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16258                // And we need to make sure at this point that all other activities
16259                // are made visible with the correct configuration.
16260                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16261            }
16262        }
16263
16264        if (values != null && mWindowManager != null) {
16265            mWindowManager.setNewConfiguration(mConfiguration);
16266        }
16267
16268        return kept;
16269    }
16270
16271    /**
16272     * Decide based on the configuration whether we should shouw the ANR,
16273     * crash, etc dialogs.  The idea is that if there is no affordnace to
16274     * press the on-screen buttons, we shouldn't show the dialog.
16275     *
16276     * A thought: SystemUI might also want to get told about this, the Power
16277     * dialog / global actions also might want different behaviors.
16278     */
16279    private static final boolean shouldShowDialogs(Configuration config) {
16280        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16281                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16282    }
16283
16284    /**
16285     * Save the locale.  You must be inside a synchronized (this) block.
16286     */
16287    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16288        if(isDiff) {
16289            SystemProperties.set("user.language", l.getLanguage());
16290            SystemProperties.set("user.region", l.getCountry());
16291        }
16292
16293        if(isPersist) {
16294            SystemProperties.set("persist.sys.language", l.getLanguage());
16295            SystemProperties.set("persist.sys.country", l.getCountry());
16296            SystemProperties.set("persist.sys.localevar", l.getVariant());
16297
16298            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16299        }
16300    }
16301
16302    @Override
16303    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16304        synchronized (this) {
16305            ActivityRecord srec = ActivityRecord.forToken(token);
16306            if (srec.task != null && srec.task.stack != null) {
16307                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16308            }
16309        }
16310        return false;
16311    }
16312
16313    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16314            Intent resultData) {
16315
16316        synchronized (this) {
16317            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16318            if (stack != null) {
16319                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16320            }
16321            return false;
16322        }
16323    }
16324
16325    public int getLaunchedFromUid(IBinder activityToken) {
16326        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16327        if (srec == null) {
16328            return -1;
16329        }
16330        return srec.launchedFromUid;
16331    }
16332
16333    public String getLaunchedFromPackage(IBinder activityToken) {
16334        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16335        if (srec == null) {
16336            return null;
16337        }
16338        return srec.launchedFromPackage;
16339    }
16340
16341    // =========================================================
16342    // LIFETIME MANAGEMENT
16343    // =========================================================
16344
16345    // Returns which broadcast queue the app is the current [or imminent] receiver
16346    // on, or 'null' if the app is not an active broadcast recipient.
16347    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16348        BroadcastRecord r = app.curReceiver;
16349        if (r != null) {
16350            return r.queue;
16351        }
16352
16353        // It's not the current receiver, but it might be starting up to become one
16354        synchronized (this) {
16355            for (BroadcastQueue queue : mBroadcastQueues) {
16356                r = queue.mPendingBroadcast;
16357                if (r != null && r.curApp == app) {
16358                    // found it; report which queue it's in
16359                    return queue;
16360                }
16361            }
16362        }
16363
16364        return null;
16365    }
16366
16367    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16368            boolean doingAll, long now) {
16369        if (mAdjSeq == app.adjSeq) {
16370            // This adjustment has already been computed.
16371            return app.curRawAdj;
16372        }
16373
16374        if (app.thread == null) {
16375            app.adjSeq = mAdjSeq;
16376            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16377            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16378            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16379        }
16380
16381        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16382        app.adjSource = null;
16383        app.adjTarget = null;
16384        app.empty = false;
16385        app.cached = false;
16386
16387        final int activitiesSize = app.activities.size();
16388
16389        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16390            // The max adjustment doesn't allow this app to be anything
16391            // below foreground, so it is not worth doing work for it.
16392            app.adjType = "fixed";
16393            app.adjSeq = mAdjSeq;
16394            app.curRawAdj = app.maxAdj;
16395            app.foregroundActivities = false;
16396            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16397            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16398            // System processes can do UI, and when they do we want to have
16399            // them trim their memory after the user leaves the UI.  To
16400            // facilitate this, here we need to determine whether or not it
16401            // is currently showing UI.
16402            app.systemNoUi = true;
16403            if (app == TOP_APP) {
16404                app.systemNoUi = false;
16405            } else if (activitiesSize > 0) {
16406                for (int j = 0; j < activitiesSize; j++) {
16407                    final ActivityRecord r = app.activities.get(j);
16408                    if (r.visible) {
16409                        app.systemNoUi = false;
16410                    }
16411                }
16412            }
16413            if (!app.systemNoUi) {
16414                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16415            }
16416            return (app.curAdj=app.maxAdj);
16417        }
16418
16419        app.systemNoUi = false;
16420
16421        // Determine the importance of the process, starting with most
16422        // important to least, and assign an appropriate OOM adjustment.
16423        int adj;
16424        int schedGroup;
16425        int procState;
16426        boolean foregroundActivities = false;
16427        BroadcastQueue queue;
16428        if (app == TOP_APP) {
16429            // The last app on the list is the foreground app.
16430            adj = ProcessList.FOREGROUND_APP_ADJ;
16431            schedGroup = Process.THREAD_GROUP_DEFAULT;
16432            app.adjType = "top-activity";
16433            foregroundActivities = true;
16434            procState = ActivityManager.PROCESS_STATE_TOP;
16435        } else if (app.instrumentationClass != null) {
16436            // Don't want to kill running instrumentation.
16437            adj = ProcessList.FOREGROUND_APP_ADJ;
16438            schedGroup = Process.THREAD_GROUP_DEFAULT;
16439            app.adjType = "instrumentation";
16440            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16441        } else if ((queue = isReceivingBroadcast(app)) != null) {
16442            // An app that is currently receiving a broadcast also
16443            // counts as being in the foreground for OOM killer purposes.
16444            // It's placed in a sched group based on the nature of the
16445            // broadcast as reflected by which queue it's active in.
16446            adj = ProcessList.FOREGROUND_APP_ADJ;
16447            schedGroup = (queue == mFgBroadcastQueue)
16448                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16449            app.adjType = "broadcast";
16450            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16451        } else if (app.executingServices.size() > 0) {
16452            // An app that is currently executing a service callback also
16453            // counts as being in the foreground.
16454            adj = ProcessList.FOREGROUND_APP_ADJ;
16455            schedGroup = app.execServicesFg ?
16456                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16457            app.adjType = "exec-service";
16458            procState = ActivityManager.PROCESS_STATE_SERVICE;
16459            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16460        } else {
16461            // As far as we know the process is empty.  We may change our mind later.
16462            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16463            // At this point we don't actually know the adjustment.  Use the cached adj
16464            // value that the caller wants us to.
16465            adj = cachedAdj;
16466            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16467            app.cached = true;
16468            app.empty = true;
16469            app.adjType = "cch-empty";
16470        }
16471
16472        // Examine all activities if not already foreground.
16473        if (!foregroundActivities && activitiesSize > 0) {
16474            for (int j = 0; j < activitiesSize; j++) {
16475                final ActivityRecord r = app.activities.get(j);
16476                if (r.app != app) {
16477                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16478                            + app + "?!?");
16479                    continue;
16480                }
16481                if (r.visible) {
16482                    // App has a visible activity; only upgrade adjustment.
16483                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16484                        adj = ProcessList.VISIBLE_APP_ADJ;
16485                        app.adjType = "visible";
16486                    }
16487                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16488                        procState = ActivityManager.PROCESS_STATE_TOP;
16489                    }
16490                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16491                    app.cached = false;
16492                    app.empty = false;
16493                    foregroundActivities = true;
16494                    break;
16495                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16496                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16497                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16498                        app.adjType = "pausing";
16499                    }
16500                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16501                        procState = ActivityManager.PROCESS_STATE_TOP;
16502                    }
16503                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16504                    app.cached = false;
16505                    app.empty = false;
16506                    foregroundActivities = true;
16507                } else if (r.state == ActivityState.STOPPING) {
16508                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16509                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16510                        app.adjType = "stopping";
16511                    }
16512                    // For the process state, we will at this point consider the
16513                    // process to be cached.  It will be cached either as an activity
16514                    // or empty depending on whether the activity is finishing.  We do
16515                    // this so that we can treat the process as cached for purposes of
16516                    // memory trimming (determing current memory level, trim command to
16517                    // send to process) since there can be an arbitrary number of stopping
16518                    // processes and they should soon all go into the cached state.
16519                    if (!r.finishing) {
16520                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16521                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16522                        }
16523                    }
16524                    app.cached = false;
16525                    app.empty = false;
16526                    foregroundActivities = true;
16527                } else {
16528                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16529                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16530                        app.adjType = "cch-act";
16531                    }
16532                }
16533            }
16534        }
16535
16536        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16537            if (app.foregroundServices) {
16538                // The user is aware of this app, so make it visible.
16539                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16540                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16541                app.cached = false;
16542                app.adjType = "fg-service";
16543                schedGroup = Process.THREAD_GROUP_DEFAULT;
16544            } else if (app.forcingToForeground != null) {
16545                // The user is aware of this app, so make it visible.
16546                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16547                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16548                app.cached = false;
16549                app.adjType = "force-fg";
16550                app.adjSource = app.forcingToForeground;
16551                schedGroup = Process.THREAD_GROUP_DEFAULT;
16552            }
16553        }
16554
16555        if (app == mHeavyWeightProcess) {
16556            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16557                // We don't want to kill the current heavy-weight process.
16558                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16559                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16560                app.cached = false;
16561                app.adjType = "heavy";
16562            }
16563            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16564                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16565            }
16566        }
16567
16568        if (app == mHomeProcess) {
16569            if (adj > ProcessList.HOME_APP_ADJ) {
16570                // This process is hosting what we currently consider to be the
16571                // home app, so we don't want to let it go into the background.
16572                adj = ProcessList.HOME_APP_ADJ;
16573                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16574                app.cached = false;
16575                app.adjType = "home";
16576            }
16577            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16578                procState = ActivityManager.PROCESS_STATE_HOME;
16579            }
16580        }
16581
16582        if (app == mPreviousProcess && app.activities.size() > 0) {
16583            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16584                // This was the previous process that showed UI to the user.
16585                // We want to try to keep it around more aggressively, to give
16586                // a good experience around switching between two apps.
16587                adj = ProcessList.PREVIOUS_APP_ADJ;
16588                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16589                app.cached = false;
16590                app.adjType = "previous";
16591            }
16592            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16593                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16594            }
16595        }
16596
16597        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16598                + " reason=" + app.adjType);
16599
16600        // By default, we use the computed adjustment.  It may be changed if
16601        // there are applications dependent on our services or providers, but
16602        // this gives us a baseline and makes sure we don't get into an
16603        // infinite recursion.
16604        app.adjSeq = mAdjSeq;
16605        app.curRawAdj = adj;
16606        app.hasStartedServices = false;
16607
16608        if (mBackupTarget != null && app == mBackupTarget.app) {
16609            // If possible we want to avoid killing apps while they're being backed up
16610            if (adj > ProcessList.BACKUP_APP_ADJ) {
16611                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16612                adj = ProcessList.BACKUP_APP_ADJ;
16613                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16614                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16615                }
16616                app.adjType = "backup";
16617                app.cached = false;
16618            }
16619            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16620                procState = ActivityManager.PROCESS_STATE_BACKUP;
16621            }
16622        }
16623
16624        boolean mayBeTop = false;
16625
16626        for (int is = app.services.size()-1;
16627                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16628                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16629                        || procState > ActivityManager.PROCESS_STATE_TOP);
16630                is--) {
16631            ServiceRecord s = app.services.valueAt(is);
16632            if (s.startRequested) {
16633                app.hasStartedServices = true;
16634                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16635                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16636                }
16637                if (app.hasShownUi && app != mHomeProcess) {
16638                    // If this process has shown some UI, let it immediately
16639                    // go to the LRU list because it may be pretty heavy with
16640                    // UI stuff.  We'll tag it with a label just to help
16641                    // debug and understand what is going on.
16642                    if (adj > ProcessList.SERVICE_ADJ) {
16643                        app.adjType = "cch-started-ui-services";
16644                    }
16645                } else {
16646                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16647                        // This service has seen some activity within
16648                        // recent memory, so we will keep its process ahead
16649                        // of the background processes.
16650                        if (adj > ProcessList.SERVICE_ADJ) {
16651                            adj = ProcessList.SERVICE_ADJ;
16652                            app.adjType = "started-services";
16653                            app.cached = false;
16654                        }
16655                    }
16656                    // If we have let the service slide into the background
16657                    // state, still have some text describing what it is doing
16658                    // even though the service no longer has an impact.
16659                    if (adj > ProcessList.SERVICE_ADJ) {
16660                        app.adjType = "cch-started-services";
16661                    }
16662                }
16663            }
16664            for (int conni = s.connections.size()-1;
16665                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16666                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16667                            || procState > ActivityManager.PROCESS_STATE_TOP);
16668                    conni--) {
16669                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16670                for (int i = 0;
16671                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16672                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16673                                || procState > ActivityManager.PROCESS_STATE_TOP);
16674                        i++) {
16675                    // XXX should compute this based on the max of
16676                    // all connected clients.
16677                    ConnectionRecord cr = clist.get(i);
16678                    if (cr.binding.client == app) {
16679                        // Binding to ourself is not interesting.
16680                        continue;
16681                    }
16682                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16683                        ProcessRecord client = cr.binding.client;
16684                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16685                                TOP_APP, doingAll, now);
16686                        int clientProcState = client.curProcState;
16687                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16688                            // If the other app is cached for any reason, for purposes here
16689                            // we are going to consider it empty.  The specific cached state
16690                            // doesn't propagate except under certain conditions.
16691                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16692                        }
16693                        String adjType = null;
16694                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16695                            // Not doing bind OOM management, so treat
16696                            // this guy more like a started service.
16697                            if (app.hasShownUi && app != mHomeProcess) {
16698                                // If this process has shown some UI, let it immediately
16699                                // go to the LRU list because it may be pretty heavy with
16700                                // UI stuff.  We'll tag it with a label just to help
16701                                // debug and understand what is going on.
16702                                if (adj > clientAdj) {
16703                                    adjType = "cch-bound-ui-services";
16704                                }
16705                                app.cached = false;
16706                                clientAdj = adj;
16707                                clientProcState = procState;
16708                            } else {
16709                                if (now >= (s.lastActivity
16710                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16711                                    // This service has not seen activity within
16712                                    // recent memory, so allow it to drop to the
16713                                    // LRU list if there is no other reason to keep
16714                                    // it around.  We'll also tag it with a label just
16715                                    // to help debug and undertand what is going on.
16716                                    if (adj > clientAdj) {
16717                                        adjType = "cch-bound-services";
16718                                    }
16719                                    clientAdj = adj;
16720                                }
16721                            }
16722                        }
16723                        if (adj > clientAdj) {
16724                            // If this process has recently shown UI, and
16725                            // the process that is binding to it is less
16726                            // important than being visible, then we don't
16727                            // care about the binding as much as we care
16728                            // about letting this process get into the LRU
16729                            // list to be killed and restarted if needed for
16730                            // memory.
16731                            if (app.hasShownUi && app != mHomeProcess
16732                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16733                                adjType = "cch-bound-ui-services";
16734                            } else {
16735                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16736                                        |Context.BIND_IMPORTANT)) != 0) {
16737                                    adj = clientAdj;
16738                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16739                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16740                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16741                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16742                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16743                                    adj = clientAdj;
16744                                } else {
16745                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16746                                        adj = ProcessList.VISIBLE_APP_ADJ;
16747                                    }
16748                                }
16749                                if (!client.cached) {
16750                                    app.cached = false;
16751                                }
16752                                adjType = "service";
16753                            }
16754                        }
16755                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16756                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16757                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16758                            }
16759                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16760                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16761                                    // Special handling of clients who are in the top state.
16762                                    // We *may* want to consider this process to be in the
16763                                    // top state as well, but only if there is not another
16764                                    // reason for it to be running.  Being on the top is a
16765                                    // special state, meaning you are specifically running
16766                                    // for the current top app.  If the process is already
16767                                    // running in the background for some other reason, it
16768                                    // is more important to continue considering it to be
16769                                    // in the background state.
16770                                    mayBeTop = true;
16771                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16772                                } else {
16773                                    // Special handling for above-top states (persistent
16774                                    // processes).  These should not bring the current process
16775                                    // into the top state, since they are not on top.  Instead
16776                                    // give them the best state after that.
16777                                    clientProcState =
16778                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16779                                }
16780                            }
16781                        } else {
16782                            if (clientProcState <
16783                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16784                                clientProcState =
16785                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16786                            }
16787                        }
16788                        if (procState > clientProcState) {
16789                            procState = clientProcState;
16790                        }
16791                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16792                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16793                            app.pendingUiClean = true;
16794                        }
16795                        if (adjType != null) {
16796                            app.adjType = adjType;
16797                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16798                                    .REASON_SERVICE_IN_USE;
16799                            app.adjSource = cr.binding.client;
16800                            app.adjSourceProcState = clientProcState;
16801                            app.adjTarget = s.name;
16802                        }
16803                    }
16804                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16805                        app.treatLikeActivity = true;
16806                    }
16807                    final ActivityRecord a = cr.activity;
16808                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16809                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16810                                (a.visible || a.state == ActivityState.RESUMED
16811                                 || a.state == ActivityState.PAUSING)) {
16812                            adj = ProcessList.FOREGROUND_APP_ADJ;
16813                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16814                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16815                            }
16816                            app.cached = false;
16817                            app.adjType = "service";
16818                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16819                                    .REASON_SERVICE_IN_USE;
16820                            app.adjSource = a;
16821                            app.adjSourceProcState = procState;
16822                            app.adjTarget = s.name;
16823                        }
16824                    }
16825                }
16826            }
16827        }
16828
16829        for (int provi = app.pubProviders.size()-1;
16830                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16831                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16832                        || procState > ActivityManager.PROCESS_STATE_TOP);
16833                provi--) {
16834            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16835            for (int i = cpr.connections.size()-1;
16836                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16837                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16838                            || procState > ActivityManager.PROCESS_STATE_TOP);
16839                    i--) {
16840                ContentProviderConnection conn = cpr.connections.get(i);
16841                ProcessRecord client = conn.client;
16842                if (client == app) {
16843                    // Being our own client is not interesting.
16844                    continue;
16845                }
16846                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16847                int clientProcState = client.curProcState;
16848                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16849                    // If the other app is cached for any reason, for purposes here
16850                    // we are going to consider it empty.
16851                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16852                }
16853                if (adj > clientAdj) {
16854                    if (app.hasShownUi && app != mHomeProcess
16855                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16856                        app.adjType = "cch-ui-provider";
16857                    } else {
16858                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16859                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16860                        app.adjType = "provider";
16861                    }
16862                    app.cached &= client.cached;
16863                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16864                            .REASON_PROVIDER_IN_USE;
16865                    app.adjSource = client;
16866                    app.adjSourceProcState = clientProcState;
16867                    app.adjTarget = cpr.name;
16868                }
16869                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16870                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16871                        // Special handling of clients who are in the top state.
16872                        // We *may* want to consider this process to be in the
16873                        // top state as well, but only if there is not another
16874                        // reason for it to be running.  Being on the top is a
16875                        // special state, meaning you are specifically running
16876                        // for the current top app.  If the process is already
16877                        // running in the background for some other reason, it
16878                        // is more important to continue considering it to be
16879                        // in the background state.
16880                        mayBeTop = true;
16881                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16882                    } else {
16883                        // Special handling for above-top states (persistent
16884                        // processes).  These should not bring the current process
16885                        // into the top state, since they are not on top.  Instead
16886                        // give them the best state after that.
16887                        clientProcState =
16888                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16889                    }
16890                }
16891                if (procState > clientProcState) {
16892                    procState = clientProcState;
16893                }
16894                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16895                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16896                }
16897            }
16898            // If the provider has external (non-framework) process
16899            // dependencies, ensure that its adjustment is at least
16900            // FOREGROUND_APP_ADJ.
16901            if (cpr.hasExternalProcessHandles()) {
16902                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16903                    adj = ProcessList.FOREGROUND_APP_ADJ;
16904                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16905                    app.cached = false;
16906                    app.adjType = "provider";
16907                    app.adjTarget = cpr.name;
16908                }
16909                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16910                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16911                }
16912            }
16913        }
16914
16915        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16916            // A client of one of our services or providers is in the top state.  We
16917            // *may* want to be in the top state, but not if we are already running in
16918            // the background for some other reason.  For the decision here, we are going
16919            // to pick out a few specific states that we want to remain in when a client
16920            // is top (states that tend to be longer-term) and otherwise allow it to go
16921            // to the top state.
16922            switch (procState) {
16923                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16924                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16925                case ActivityManager.PROCESS_STATE_SERVICE:
16926                    // These all are longer-term states, so pull them up to the top
16927                    // of the background states, but not all the way to the top state.
16928                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16929                    break;
16930                default:
16931                    // Otherwise, top is a better choice, so take it.
16932                    procState = ActivityManager.PROCESS_STATE_TOP;
16933                    break;
16934            }
16935        }
16936
16937        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16938            if (app.hasClientActivities) {
16939                // This is a cached process, but with client activities.  Mark it so.
16940                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16941                app.adjType = "cch-client-act";
16942            } else if (app.treatLikeActivity) {
16943                // This is a cached process, but somebody wants us to treat it like it has
16944                // an activity, okay!
16945                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16946                app.adjType = "cch-as-act";
16947            }
16948        }
16949
16950        if (adj == ProcessList.SERVICE_ADJ) {
16951            if (doingAll) {
16952                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16953                mNewNumServiceProcs++;
16954                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16955                if (!app.serviceb) {
16956                    // This service isn't far enough down on the LRU list to
16957                    // normally be a B service, but if we are low on RAM and it
16958                    // is large we want to force it down since we would prefer to
16959                    // keep launcher over it.
16960                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16961                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16962                        app.serviceHighRam = true;
16963                        app.serviceb = true;
16964                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16965                    } else {
16966                        mNewNumAServiceProcs++;
16967                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16968                    }
16969                } else {
16970                    app.serviceHighRam = false;
16971                }
16972            }
16973            if (app.serviceb) {
16974                adj = ProcessList.SERVICE_B_ADJ;
16975            }
16976        }
16977
16978        app.curRawAdj = adj;
16979
16980        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16981        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16982        if (adj > app.maxAdj) {
16983            adj = app.maxAdj;
16984            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16985                schedGroup = Process.THREAD_GROUP_DEFAULT;
16986            }
16987        }
16988
16989        // Do final modification to adj.  Everything we do between here and applying
16990        // the final setAdj must be done in this function, because we will also use
16991        // it when computing the final cached adj later.  Note that we don't need to
16992        // worry about this for max adj above, since max adj will always be used to
16993        // keep it out of the cached vaues.
16994        app.curAdj = app.modifyRawOomAdj(adj);
16995        app.curSchedGroup = schedGroup;
16996        app.curProcState = procState;
16997        app.foregroundActivities = foregroundActivities;
16998
16999        return app.curRawAdj;
17000    }
17001
17002    /**
17003     * Schedule PSS collection of a process.
17004     */
17005    void requestPssLocked(ProcessRecord proc, int procState) {
17006        if (mPendingPssProcesses.contains(proc)) {
17007            return;
17008        }
17009        if (mPendingPssProcesses.size() == 0) {
17010            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17011        }
17012        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17013        proc.pssProcState = procState;
17014        mPendingPssProcesses.add(proc);
17015    }
17016
17017    /**
17018     * Schedule PSS collection of all processes.
17019     */
17020    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17021        if (!always) {
17022            if (now < (mLastFullPssTime +
17023                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17024                return;
17025            }
17026        }
17027        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17028        mLastFullPssTime = now;
17029        mFullPssPending = true;
17030        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17031        mPendingPssProcesses.clear();
17032        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17033            ProcessRecord app = mLruProcesses.get(i);
17034            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17035                app.pssProcState = app.setProcState;
17036                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17037                        isSleeping(), now);
17038                mPendingPssProcesses.add(app);
17039            }
17040        }
17041        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17042    }
17043
17044    /**
17045     * Ask a given process to GC right now.
17046     */
17047    final void performAppGcLocked(ProcessRecord app) {
17048        try {
17049            app.lastRequestedGc = SystemClock.uptimeMillis();
17050            if (app.thread != null) {
17051                if (app.reportLowMemory) {
17052                    app.reportLowMemory = false;
17053                    app.thread.scheduleLowMemory();
17054                } else {
17055                    app.thread.processInBackground();
17056                }
17057            }
17058        } catch (Exception e) {
17059            // whatever.
17060        }
17061    }
17062
17063    /**
17064     * Returns true if things are idle enough to perform GCs.
17065     */
17066    private final boolean canGcNowLocked() {
17067        boolean processingBroadcasts = false;
17068        for (BroadcastQueue q : mBroadcastQueues) {
17069            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17070                processingBroadcasts = true;
17071            }
17072        }
17073        return !processingBroadcasts
17074                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17075    }
17076
17077    /**
17078     * Perform GCs on all processes that are waiting for it, but only
17079     * if things are idle.
17080     */
17081    final void performAppGcsLocked() {
17082        final int N = mProcessesToGc.size();
17083        if (N <= 0) {
17084            return;
17085        }
17086        if (canGcNowLocked()) {
17087            while (mProcessesToGc.size() > 0) {
17088                ProcessRecord proc = mProcessesToGc.remove(0);
17089                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17090                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17091                            <= SystemClock.uptimeMillis()) {
17092                        // To avoid spamming the system, we will GC processes one
17093                        // at a time, waiting a few seconds between each.
17094                        performAppGcLocked(proc);
17095                        scheduleAppGcsLocked();
17096                        return;
17097                    } else {
17098                        // It hasn't been long enough since we last GCed this
17099                        // process...  put it in the list to wait for its time.
17100                        addProcessToGcListLocked(proc);
17101                        break;
17102                    }
17103                }
17104            }
17105
17106            scheduleAppGcsLocked();
17107        }
17108    }
17109
17110    /**
17111     * If all looks good, perform GCs on all processes waiting for them.
17112     */
17113    final void performAppGcsIfAppropriateLocked() {
17114        if (canGcNowLocked()) {
17115            performAppGcsLocked();
17116            return;
17117        }
17118        // Still not idle, wait some more.
17119        scheduleAppGcsLocked();
17120    }
17121
17122    /**
17123     * Schedule the execution of all pending app GCs.
17124     */
17125    final void scheduleAppGcsLocked() {
17126        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17127
17128        if (mProcessesToGc.size() > 0) {
17129            // Schedule a GC for the time to the next process.
17130            ProcessRecord proc = mProcessesToGc.get(0);
17131            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17132
17133            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17134            long now = SystemClock.uptimeMillis();
17135            if (when < (now+GC_TIMEOUT)) {
17136                when = now + GC_TIMEOUT;
17137            }
17138            mHandler.sendMessageAtTime(msg, when);
17139        }
17140    }
17141
17142    /**
17143     * Add a process to the array of processes waiting to be GCed.  Keeps the
17144     * list in sorted order by the last GC time.  The process can't already be
17145     * on the list.
17146     */
17147    final void addProcessToGcListLocked(ProcessRecord proc) {
17148        boolean added = false;
17149        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17150            if (mProcessesToGc.get(i).lastRequestedGc <
17151                    proc.lastRequestedGc) {
17152                added = true;
17153                mProcessesToGc.add(i+1, proc);
17154                break;
17155            }
17156        }
17157        if (!added) {
17158            mProcessesToGc.add(0, proc);
17159        }
17160    }
17161
17162    /**
17163     * Set up to ask a process to GC itself.  This will either do it
17164     * immediately, or put it on the list of processes to gc the next
17165     * time things are idle.
17166     */
17167    final void scheduleAppGcLocked(ProcessRecord app) {
17168        long now = SystemClock.uptimeMillis();
17169        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17170            return;
17171        }
17172        if (!mProcessesToGc.contains(app)) {
17173            addProcessToGcListLocked(app);
17174            scheduleAppGcsLocked();
17175        }
17176    }
17177
17178    final void checkExcessivePowerUsageLocked(boolean doKills) {
17179        updateCpuStatsNow();
17180
17181        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17182        boolean doWakeKills = doKills;
17183        boolean doCpuKills = doKills;
17184        if (mLastPowerCheckRealtime == 0) {
17185            doWakeKills = false;
17186        }
17187        if (mLastPowerCheckUptime == 0) {
17188            doCpuKills = false;
17189        }
17190        if (stats.isScreenOn()) {
17191            doWakeKills = false;
17192        }
17193        final long curRealtime = SystemClock.elapsedRealtime();
17194        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17195        final long curUptime = SystemClock.uptimeMillis();
17196        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17197        mLastPowerCheckRealtime = curRealtime;
17198        mLastPowerCheckUptime = curUptime;
17199        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17200            doWakeKills = false;
17201        }
17202        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17203            doCpuKills = false;
17204        }
17205        int i = mLruProcesses.size();
17206        while (i > 0) {
17207            i--;
17208            ProcessRecord app = mLruProcesses.get(i);
17209            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17210                long wtime;
17211                synchronized (stats) {
17212                    wtime = stats.getProcessWakeTime(app.info.uid,
17213                            app.pid, curRealtime);
17214                }
17215                long wtimeUsed = wtime - app.lastWakeTime;
17216                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17217                if (DEBUG_POWER) {
17218                    StringBuilder sb = new StringBuilder(128);
17219                    sb.append("Wake for ");
17220                    app.toShortString(sb);
17221                    sb.append(": over ");
17222                    TimeUtils.formatDuration(realtimeSince, sb);
17223                    sb.append(" used ");
17224                    TimeUtils.formatDuration(wtimeUsed, sb);
17225                    sb.append(" (");
17226                    sb.append((wtimeUsed*100)/realtimeSince);
17227                    sb.append("%)");
17228                    Slog.i(TAG, sb.toString());
17229                    sb.setLength(0);
17230                    sb.append("CPU for ");
17231                    app.toShortString(sb);
17232                    sb.append(": over ");
17233                    TimeUtils.formatDuration(uptimeSince, sb);
17234                    sb.append(" used ");
17235                    TimeUtils.formatDuration(cputimeUsed, sb);
17236                    sb.append(" (");
17237                    sb.append((cputimeUsed*100)/uptimeSince);
17238                    sb.append("%)");
17239                    Slog.i(TAG, sb.toString());
17240                }
17241                // If a process has held a wake lock for more
17242                // than 50% of the time during this period,
17243                // that sounds bad.  Kill!
17244                if (doWakeKills && realtimeSince > 0
17245                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17246                    synchronized (stats) {
17247                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17248                                realtimeSince, wtimeUsed);
17249                    }
17250                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17251                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17252                } else if (doCpuKills && uptimeSince > 0
17253                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17254                    synchronized (stats) {
17255                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17256                                uptimeSince, cputimeUsed);
17257                    }
17258                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17259                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17260                } else {
17261                    app.lastWakeTime = wtime;
17262                    app.lastCpuTime = app.curCpuTime;
17263                }
17264            }
17265        }
17266    }
17267
17268    private final boolean applyOomAdjLocked(ProcessRecord app,
17269            ProcessRecord TOP_APP, boolean doingAll, long now) {
17270        boolean success = true;
17271
17272        if (app.curRawAdj != app.setRawAdj) {
17273            app.setRawAdj = app.curRawAdj;
17274        }
17275
17276        int changes = 0;
17277
17278        if (app.curAdj != app.setAdj) {
17279            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17280            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17281                TAG, "Set " + app.pid + " " + app.processName +
17282                " adj " + app.curAdj + ": " + app.adjType);
17283            app.setAdj = app.curAdj;
17284        }
17285
17286        if (app.setSchedGroup != app.curSchedGroup) {
17287            app.setSchedGroup = app.curSchedGroup;
17288            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17289                    "Setting process group of " + app.processName
17290                    + " to " + app.curSchedGroup);
17291            if (app.waitingToKill != null &&
17292                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17293                app.kill(app.waitingToKill, true);
17294                success = false;
17295            } else {
17296                if (true) {
17297                    long oldId = Binder.clearCallingIdentity();
17298                    try {
17299                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17300                    } catch (Exception e) {
17301                        Slog.w(TAG, "Failed setting process group of " + app.pid
17302                                + " to " + app.curSchedGroup);
17303                        e.printStackTrace();
17304                    } finally {
17305                        Binder.restoreCallingIdentity(oldId);
17306                    }
17307                } else {
17308                    if (app.thread != null) {
17309                        try {
17310                            app.thread.setSchedulingGroup(app.curSchedGroup);
17311                        } catch (RemoteException e) {
17312                        }
17313                    }
17314                }
17315                Process.setSwappiness(app.pid,
17316                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17317            }
17318        }
17319        if (app.repForegroundActivities != app.foregroundActivities) {
17320            app.repForegroundActivities = app.foregroundActivities;
17321            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17322        }
17323        if (app.repProcState != app.curProcState) {
17324            app.repProcState = app.curProcState;
17325            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17326            if (app.thread != null) {
17327                try {
17328                    if (false) {
17329                        //RuntimeException h = new RuntimeException("here");
17330                        Slog.i(TAG, "Sending new process state " + app.repProcState
17331                                + " to " + app /*, h*/);
17332                    }
17333                    app.thread.setProcessState(app.repProcState);
17334                } catch (RemoteException e) {
17335                }
17336            }
17337        }
17338        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17339                app.setProcState)) {
17340            app.lastStateTime = now;
17341            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17342                    isSleeping(), now);
17343            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17344                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17345                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17346                    + (app.nextPssTime-now) + ": " + app);
17347        } else {
17348            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17349                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17350                requestPssLocked(app, app.setProcState);
17351                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17352                        isSleeping(), now);
17353            } else if (false && DEBUG_PSS) {
17354                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17355            }
17356        }
17357        if (app.setProcState != app.curProcState) {
17358            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17359                    "Proc state change of " + app.processName
17360                    + " to " + app.curProcState);
17361            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17362            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17363            if (setImportant && !curImportant) {
17364                // This app is no longer something we consider important enough to allow to
17365                // use arbitrary amounts of battery power.  Note
17366                // its current wake lock time to later know to kill it if
17367                // it is not behaving well.
17368                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17369                synchronized (stats) {
17370                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17371                            app.pid, SystemClock.elapsedRealtime());
17372                }
17373                app.lastCpuTime = app.curCpuTime;
17374
17375            }
17376            app.setProcState = app.curProcState;
17377            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17378                app.notCachedSinceIdle = false;
17379            }
17380            if (!doingAll) {
17381                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17382            } else {
17383                app.procStateChanged = true;
17384            }
17385        }
17386
17387        if (changes != 0) {
17388            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17389            int i = mPendingProcessChanges.size()-1;
17390            ProcessChangeItem item = null;
17391            while (i >= 0) {
17392                item = mPendingProcessChanges.get(i);
17393                if (item.pid == app.pid) {
17394                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17395                    break;
17396                }
17397                i--;
17398            }
17399            if (i < 0) {
17400                // No existing item in pending changes; need a new one.
17401                final int NA = mAvailProcessChanges.size();
17402                if (NA > 0) {
17403                    item = mAvailProcessChanges.remove(NA-1);
17404                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17405                } else {
17406                    item = new ProcessChangeItem();
17407                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17408                }
17409                item.changes = 0;
17410                item.pid = app.pid;
17411                item.uid = app.info.uid;
17412                if (mPendingProcessChanges.size() == 0) {
17413                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17414                            "*** Enqueueing dispatch processes changed!");
17415                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17416                }
17417                mPendingProcessChanges.add(item);
17418            }
17419            item.changes |= changes;
17420            item.processState = app.repProcState;
17421            item.foregroundActivities = app.repForegroundActivities;
17422            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17423                    + Integer.toHexString(System.identityHashCode(item))
17424                    + " " + app.toShortString() + ": changes=" + item.changes
17425                    + " procState=" + item.processState
17426                    + " foreground=" + item.foregroundActivities
17427                    + " type=" + app.adjType + " source=" + app.adjSource
17428                    + " target=" + app.adjTarget);
17429        }
17430
17431        return success;
17432    }
17433
17434    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17435        if (proc.thread != null) {
17436            if (proc.baseProcessTracker != null) {
17437                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17438            }
17439            if (proc.repProcState >= 0) {
17440                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17441                        proc.repProcState);
17442            }
17443        }
17444    }
17445
17446    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17447            ProcessRecord TOP_APP, boolean doingAll, long now) {
17448        if (app.thread == null) {
17449            return false;
17450        }
17451
17452        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17453
17454        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17455    }
17456
17457    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17458            boolean oomAdj) {
17459        if (isForeground != proc.foregroundServices) {
17460            proc.foregroundServices = isForeground;
17461            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17462                    proc.info.uid);
17463            if (isForeground) {
17464                if (curProcs == null) {
17465                    curProcs = new ArrayList<ProcessRecord>();
17466                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17467                }
17468                if (!curProcs.contains(proc)) {
17469                    curProcs.add(proc);
17470                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17471                            proc.info.packageName, proc.info.uid);
17472                }
17473            } else {
17474                if (curProcs != null) {
17475                    if (curProcs.remove(proc)) {
17476                        mBatteryStatsService.noteEvent(
17477                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17478                                proc.info.packageName, proc.info.uid);
17479                        if (curProcs.size() <= 0) {
17480                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17481                        }
17482                    }
17483                }
17484            }
17485            if (oomAdj) {
17486                updateOomAdjLocked();
17487            }
17488        }
17489    }
17490
17491    private final ActivityRecord resumedAppLocked() {
17492        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17493        String pkg;
17494        int uid;
17495        if (act != null) {
17496            pkg = act.packageName;
17497            uid = act.info.applicationInfo.uid;
17498        } else {
17499            pkg = null;
17500            uid = -1;
17501        }
17502        // Has the UID or resumed package name changed?
17503        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17504                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17505            if (mCurResumedPackage != null) {
17506                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17507                        mCurResumedPackage, mCurResumedUid);
17508            }
17509            mCurResumedPackage = pkg;
17510            mCurResumedUid = uid;
17511            if (mCurResumedPackage != null) {
17512                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17513                        mCurResumedPackage, mCurResumedUid);
17514            }
17515        }
17516        return act;
17517    }
17518
17519    final boolean updateOomAdjLocked(ProcessRecord app) {
17520        final ActivityRecord TOP_ACT = resumedAppLocked();
17521        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17522        final boolean wasCached = app.cached;
17523
17524        mAdjSeq++;
17525
17526        // This is the desired cached adjusment we want to tell it to use.
17527        // If our app is currently cached, we know it, and that is it.  Otherwise,
17528        // we don't know it yet, and it needs to now be cached we will then
17529        // need to do a complete oom adj.
17530        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17531                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17532        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17533                SystemClock.uptimeMillis());
17534        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17535            // Changed to/from cached state, so apps after it in the LRU
17536            // list may also be changed.
17537            updateOomAdjLocked();
17538        }
17539        return success;
17540    }
17541
17542    final void updateOomAdjLocked() {
17543        final ActivityRecord TOP_ACT = resumedAppLocked();
17544        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17545        final long now = SystemClock.uptimeMillis();
17546        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17547        final int N = mLruProcesses.size();
17548
17549        if (false) {
17550            RuntimeException e = new RuntimeException();
17551            e.fillInStackTrace();
17552            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17553        }
17554
17555        mAdjSeq++;
17556        mNewNumServiceProcs = 0;
17557        mNewNumAServiceProcs = 0;
17558
17559        final int emptyProcessLimit;
17560        final int cachedProcessLimit;
17561        if (mProcessLimit <= 0) {
17562            emptyProcessLimit = cachedProcessLimit = 0;
17563        } else if (mProcessLimit == 1) {
17564            emptyProcessLimit = 1;
17565            cachedProcessLimit = 0;
17566        } else {
17567            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17568            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17569        }
17570
17571        // Let's determine how many processes we have running vs.
17572        // how many slots we have for background processes; we may want
17573        // to put multiple processes in a slot of there are enough of
17574        // them.
17575        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17576                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17577        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17578        if (numEmptyProcs > cachedProcessLimit) {
17579            // If there are more empty processes than our limit on cached
17580            // processes, then use the cached process limit for the factor.
17581            // This ensures that the really old empty processes get pushed
17582            // down to the bottom, so if we are running low on memory we will
17583            // have a better chance at keeping around more cached processes
17584            // instead of a gazillion empty processes.
17585            numEmptyProcs = cachedProcessLimit;
17586        }
17587        int emptyFactor = numEmptyProcs/numSlots;
17588        if (emptyFactor < 1) emptyFactor = 1;
17589        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17590        if (cachedFactor < 1) cachedFactor = 1;
17591        int stepCached = 0;
17592        int stepEmpty = 0;
17593        int numCached = 0;
17594        int numEmpty = 0;
17595        int numTrimming = 0;
17596
17597        mNumNonCachedProcs = 0;
17598        mNumCachedHiddenProcs = 0;
17599
17600        // First update the OOM adjustment for each of the
17601        // application processes based on their current state.
17602        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17603        int nextCachedAdj = curCachedAdj+1;
17604        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17605        int nextEmptyAdj = curEmptyAdj+2;
17606        for (int i=N-1; i>=0; i--) {
17607            ProcessRecord app = mLruProcesses.get(i);
17608            if (!app.killedByAm && app.thread != null) {
17609                app.procStateChanged = false;
17610                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17611
17612                // If we haven't yet assigned the final cached adj
17613                // to the process, do that now.
17614                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17615                    switch (app.curProcState) {
17616                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17617                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17618                            // This process is a cached process holding activities...
17619                            // assign it the next cached value for that type, and then
17620                            // step that cached level.
17621                            app.curRawAdj = curCachedAdj;
17622                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17623                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17624                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17625                                    + ")");
17626                            if (curCachedAdj != nextCachedAdj) {
17627                                stepCached++;
17628                                if (stepCached >= cachedFactor) {
17629                                    stepCached = 0;
17630                                    curCachedAdj = nextCachedAdj;
17631                                    nextCachedAdj += 2;
17632                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17633                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17634                                    }
17635                                }
17636                            }
17637                            break;
17638                        default:
17639                            // For everything else, assign next empty cached process
17640                            // level and bump that up.  Note that this means that
17641                            // long-running services that have dropped down to the
17642                            // cached level will be treated as empty (since their process
17643                            // state is still as a service), which is what we want.
17644                            app.curRawAdj = curEmptyAdj;
17645                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17646                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17647                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17648                                    + ")");
17649                            if (curEmptyAdj != nextEmptyAdj) {
17650                                stepEmpty++;
17651                                if (stepEmpty >= emptyFactor) {
17652                                    stepEmpty = 0;
17653                                    curEmptyAdj = nextEmptyAdj;
17654                                    nextEmptyAdj += 2;
17655                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17656                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17657                                    }
17658                                }
17659                            }
17660                            break;
17661                    }
17662                }
17663
17664                applyOomAdjLocked(app, TOP_APP, true, now);
17665
17666                // Count the number of process types.
17667                switch (app.curProcState) {
17668                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17669                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17670                        mNumCachedHiddenProcs++;
17671                        numCached++;
17672                        if (numCached > cachedProcessLimit) {
17673                            app.kill("cached #" + numCached, true);
17674                        }
17675                        break;
17676                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17677                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17678                                && app.lastActivityTime < oldTime) {
17679                            app.kill("empty for "
17680                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17681                                    / 1000) + "s", true);
17682                        } else {
17683                            numEmpty++;
17684                            if (numEmpty > emptyProcessLimit) {
17685                                app.kill("empty #" + numEmpty, true);
17686                            }
17687                        }
17688                        break;
17689                    default:
17690                        mNumNonCachedProcs++;
17691                        break;
17692                }
17693
17694                if (app.isolated && app.services.size() <= 0) {
17695                    // If this is an isolated process, and there are no
17696                    // services running in it, then the process is no longer
17697                    // needed.  We agressively kill these because we can by
17698                    // definition not re-use the same process again, and it is
17699                    // good to avoid having whatever code was running in them
17700                    // left sitting around after no longer needed.
17701                    app.kill("isolated not needed", true);
17702                }
17703
17704                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17705                        && !app.killedByAm) {
17706                    numTrimming++;
17707                }
17708            }
17709        }
17710
17711        mNumServiceProcs = mNewNumServiceProcs;
17712
17713        // Now determine the memory trimming level of background processes.
17714        // Unfortunately we need to start at the back of the list to do this
17715        // properly.  We only do this if the number of background apps we
17716        // are managing to keep around is less than half the maximum we desire;
17717        // if we are keeping a good number around, we'll let them use whatever
17718        // memory they want.
17719        final int numCachedAndEmpty = numCached + numEmpty;
17720        int memFactor;
17721        if (numCached <= ProcessList.TRIM_CACHED_APPS
17722                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17723            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17724                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17725            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17726                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17727            } else {
17728                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17729            }
17730        } else {
17731            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17732        }
17733        // We always allow the memory level to go up (better).  We only allow it to go
17734        // down if we are in a state where that is allowed, *and* the total number of processes
17735        // has gone down since last time.
17736        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17737                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17738                + " last=" + mLastNumProcesses);
17739        if (memFactor > mLastMemoryLevel) {
17740            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17741                memFactor = mLastMemoryLevel;
17742                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17743            }
17744        }
17745        mLastMemoryLevel = memFactor;
17746        mLastNumProcesses = mLruProcesses.size();
17747        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17748        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17749        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17750            if (mLowRamStartTime == 0) {
17751                mLowRamStartTime = now;
17752            }
17753            int step = 0;
17754            int fgTrimLevel;
17755            switch (memFactor) {
17756                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17757                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17758                    break;
17759                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17760                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17761                    break;
17762                default:
17763                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17764                    break;
17765            }
17766            int factor = numTrimming/3;
17767            int minFactor = 2;
17768            if (mHomeProcess != null) minFactor++;
17769            if (mPreviousProcess != null) minFactor++;
17770            if (factor < minFactor) factor = minFactor;
17771            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17772            for (int i=N-1; i>=0; i--) {
17773                ProcessRecord app = mLruProcesses.get(i);
17774                if (allChanged || app.procStateChanged) {
17775                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17776                    app.procStateChanged = false;
17777                }
17778                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17779                        && !app.killedByAm) {
17780                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17781                        try {
17782                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17783                                    "Trimming memory of " + app.processName
17784                                    + " to " + curLevel);
17785                            app.thread.scheduleTrimMemory(curLevel);
17786                        } catch (RemoteException e) {
17787                        }
17788                        if (false) {
17789                            // For now we won't do this; our memory trimming seems
17790                            // to be good enough at this point that destroying
17791                            // activities causes more harm than good.
17792                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17793                                    && app != mHomeProcess && app != mPreviousProcess) {
17794                                // Need to do this on its own message because the stack may not
17795                                // be in a consistent state at this point.
17796                                // For these apps we will also finish their activities
17797                                // to help them free memory.
17798                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17799                            }
17800                        }
17801                    }
17802                    app.trimMemoryLevel = curLevel;
17803                    step++;
17804                    if (step >= factor) {
17805                        step = 0;
17806                        switch (curLevel) {
17807                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17808                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17809                                break;
17810                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17811                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17812                                break;
17813                        }
17814                    }
17815                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17816                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17817                            && app.thread != null) {
17818                        try {
17819                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17820                                    "Trimming memory of heavy-weight " + app.processName
17821                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17822                            app.thread.scheduleTrimMemory(
17823                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17824                        } catch (RemoteException e) {
17825                        }
17826                    }
17827                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17828                } else {
17829                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17830                            || app.systemNoUi) && app.pendingUiClean) {
17831                        // If this application is now in the background and it
17832                        // had done UI, then give it the special trim level to
17833                        // have it free UI resources.
17834                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17835                        if (app.trimMemoryLevel < level && app.thread != null) {
17836                            try {
17837                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17838                                        "Trimming memory of bg-ui " + app.processName
17839                                        + " to " + level);
17840                                app.thread.scheduleTrimMemory(level);
17841                            } catch (RemoteException e) {
17842                            }
17843                        }
17844                        app.pendingUiClean = false;
17845                    }
17846                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17847                        try {
17848                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17849                                    "Trimming memory of fg " + app.processName
17850                                    + " to " + fgTrimLevel);
17851                            app.thread.scheduleTrimMemory(fgTrimLevel);
17852                        } catch (RemoteException e) {
17853                        }
17854                    }
17855                    app.trimMemoryLevel = fgTrimLevel;
17856                }
17857            }
17858        } else {
17859            if (mLowRamStartTime != 0) {
17860                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17861                mLowRamStartTime = 0;
17862            }
17863            for (int i=N-1; i>=0; i--) {
17864                ProcessRecord app = mLruProcesses.get(i);
17865                if (allChanged || app.procStateChanged) {
17866                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17867                    app.procStateChanged = false;
17868                }
17869                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17870                        || app.systemNoUi) && app.pendingUiClean) {
17871                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17872                            && app.thread != null) {
17873                        try {
17874                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17875                                    "Trimming memory of ui hidden " + app.processName
17876                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17877                            app.thread.scheduleTrimMemory(
17878                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17879                        } catch (RemoteException e) {
17880                        }
17881                    }
17882                    app.pendingUiClean = false;
17883                }
17884                app.trimMemoryLevel = 0;
17885            }
17886        }
17887
17888        if (mAlwaysFinishActivities) {
17889            // Need to do this on its own message because the stack may not
17890            // be in a consistent state at this point.
17891            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17892        }
17893
17894        if (allChanged) {
17895            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17896        }
17897
17898        if (mProcessStats.shouldWriteNowLocked(now)) {
17899            mHandler.post(new Runnable() {
17900                @Override public void run() {
17901                    synchronized (ActivityManagerService.this) {
17902                        mProcessStats.writeStateAsyncLocked();
17903                    }
17904                }
17905            });
17906        }
17907
17908        if (DEBUG_OOM_ADJ) {
17909            if (false) {
17910                RuntimeException here = new RuntimeException("here");
17911                here.fillInStackTrace();
17912                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17913            } else {
17914                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17915            }
17916        }
17917    }
17918
17919    final void trimApplications() {
17920        synchronized (this) {
17921            int i;
17922
17923            // First remove any unused application processes whose package
17924            // has been removed.
17925            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17926                final ProcessRecord app = mRemovedProcesses.get(i);
17927                if (app.activities.size() == 0
17928                        && app.curReceiver == null && app.services.size() == 0) {
17929                    Slog.i(
17930                        TAG, "Exiting empty application process "
17931                        + app.processName + " ("
17932                        + (app.thread != null ? app.thread.asBinder() : null)
17933                        + ")\n");
17934                    if (app.pid > 0 && app.pid != MY_PID) {
17935                        app.kill("empty", false);
17936                    } else {
17937                        try {
17938                            app.thread.scheduleExit();
17939                        } catch (Exception e) {
17940                            // Ignore exceptions.
17941                        }
17942                    }
17943                    cleanUpApplicationRecordLocked(app, false, true, -1);
17944                    mRemovedProcesses.remove(i);
17945
17946                    if (app.persistent) {
17947                        addAppLocked(app.info, false, null /* ABI override */);
17948                    }
17949                }
17950            }
17951
17952            // Now update the oom adj for all processes.
17953            updateOomAdjLocked();
17954        }
17955    }
17956
17957    /** This method sends the specified signal to each of the persistent apps */
17958    public void signalPersistentProcesses(int sig) throws RemoteException {
17959        if (sig != Process.SIGNAL_USR1) {
17960            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17961        }
17962
17963        synchronized (this) {
17964            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17965                    != PackageManager.PERMISSION_GRANTED) {
17966                throw new SecurityException("Requires permission "
17967                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17968            }
17969
17970            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17971                ProcessRecord r = mLruProcesses.get(i);
17972                if (r.thread != null && r.persistent) {
17973                    Process.sendSignal(r.pid, sig);
17974                }
17975            }
17976        }
17977    }
17978
17979    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17980        if (proc == null || proc == mProfileProc) {
17981            proc = mProfileProc;
17982            profileType = mProfileType;
17983            clearProfilerLocked();
17984        }
17985        if (proc == null) {
17986            return;
17987        }
17988        try {
17989            proc.thread.profilerControl(false, null, profileType);
17990        } catch (RemoteException e) {
17991            throw new IllegalStateException("Process disappeared");
17992        }
17993    }
17994
17995    private void clearProfilerLocked() {
17996        if (mProfileFd != null) {
17997            try {
17998                mProfileFd.close();
17999            } catch (IOException e) {
18000            }
18001        }
18002        mProfileApp = null;
18003        mProfileProc = null;
18004        mProfileFile = null;
18005        mProfileType = 0;
18006        mAutoStopProfiler = false;
18007        mSamplingInterval = 0;
18008    }
18009
18010    public boolean profileControl(String process, int userId, boolean start,
18011            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18012
18013        try {
18014            synchronized (this) {
18015                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18016                // its own permission.
18017                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18018                        != PackageManager.PERMISSION_GRANTED) {
18019                    throw new SecurityException("Requires permission "
18020                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18021                }
18022
18023                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18024                    throw new IllegalArgumentException("null profile info or fd");
18025                }
18026
18027                ProcessRecord proc = null;
18028                if (process != null) {
18029                    proc = findProcessLocked(process, userId, "profileControl");
18030                }
18031
18032                if (start && (proc == null || proc.thread == null)) {
18033                    throw new IllegalArgumentException("Unknown process: " + process);
18034                }
18035
18036                if (start) {
18037                    stopProfilerLocked(null, 0);
18038                    setProfileApp(proc.info, proc.processName, profilerInfo);
18039                    mProfileProc = proc;
18040                    mProfileType = profileType;
18041                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18042                    try {
18043                        fd = fd.dup();
18044                    } catch (IOException e) {
18045                        fd = null;
18046                    }
18047                    profilerInfo.profileFd = fd;
18048                    proc.thread.profilerControl(start, profilerInfo, profileType);
18049                    fd = null;
18050                    mProfileFd = null;
18051                } else {
18052                    stopProfilerLocked(proc, profileType);
18053                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18054                        try {
18055                            profilerInfo.profileFd.close();
18056                        } catch (IOException e) {
18057                        }
18058                    }
18059                }
18060
18061                return true;
18062            }
18063        } catch (RemoteException e) {
18064            throw new IllegalStateException("Process disappeared");
18065        } finally {
18066            if (profilerInfo != null && profilerInfo.profileFd != null) {
18067                try {
18068                    profilerInfo.profileFd.close();
18069                } catch (IOException e) {
18070                }
18071            }
18072        }
18073    }
18074
18075    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18076        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18077                userId, true, ALLOW_FULL_ONLY, callName, null);
18078        ProcessRecord proc = null;
18079        try {
18080            int pid = Integer.parseInt(process);
18081            synchronized (mPidsSelfLocked) {
18082                proc = mPidsSelfLocked.get(pid);
18083            }
18084        } catch (NumberFormatException e) {
18085        }
18086
18087        if (proc == null) {
18088            ArrayMap<String, SparseArray<ProcessRecord>> all
18089                    = mProcessNames.getMap();
18090            SparseArray<ProcessRecord> procs = all.get(process);
18091            if (procs != null && procs.size() > 0) {
18092                proc = procs.valueAt(0);
18093                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18094                    for (int i=1; i<procs.size(); i++) {
18095                        ProcessRecord thisProc = procs.valueAt(i);
18096                        if (thisProc.userId == userId) {
18097                            proc = thisProc;
18098                            break;
18099                        }
18100                    }
18101                }
18102            }
18103        }
18104
18105        return proc;
18106    }
18107
18108    public boolean dumpHeap(String process, int userId, boolean managed,
18109            String path, ParcelFileDescriptor fd) throws RemoteException {
18110
18111        try {
18112            synchronized (this) {
18113                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18114                // its own permission (same as profileControl).
18115                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18116                        != PackageManager.PERMISSION_GRANTED) {
18117                    throw new SecurityException("Requires permission "
18118                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18119                }
18120
18121                if (fd == null) {
18122                    throw new IllegalArgumentException("null fd");
18123                }
18124
18125                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18126                if (proc == null || proc.thread == null) {
18127                    throw new IllegalArgumentException("Unknown process: " + process);
18128                }
18129
18130                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18131                if (!isDebuggable) {
18132                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18133                        throw new SecurityException("Process not debuggable: " + proc);
18134                    }
18135                }
18136
18137                proc.thread.dumpHeap(managed, path, fd);
18138                fd = null;
18139                return true;
18140            }
18141        } catch (RemoteException e) {
18142            throw new IllegalStateException("Process disappeared");
18143        } finally {
18144            if (fd != null) {
18145                try {
18146                    fd.close();
18147                } catch (IOException e) {
18148                }
18149            }
18150        }
18151    }
18152
18153    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18154    public void monitor() {
18155        synchronized (this) { }
18156    }
18157
18158    void onCoreSettingsChange(Bundle settings) {
18159        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18160            ProcessRecord processRecord = mLruProcesses.get(i);
18161            try {
18162                if (processRecord.thread != null) {
18163                    processRecord.thread.setCoreSettings(settings);
18164                }
18165            } catch (RemoteException re) {
18166                /* ignore */
18167            }
18168        }
18169    }
18170
18171    // Multi-user methods
18172
18173    /**
18174     * Start user, if its not already running, but don't bring it to foreground.
18175     */
18176    @Override
18177    public boolean startUserInBackground(final int userId) {
18178        return startUser(userId, /* foreground */ false);
18179    }
18180
18181    /**
18182     * Start user, if its not already running, and bring it to foreground.
18183     */
18184    boolean startUserInForeground(final int userId, Dialog dlg) {
18185        boolean result = startUser(userId, /* foreground */ true);
18186        dlg.dismiss();
18187        return result;
18188    }
18189
18190    /**
18191     * Refreshes the list of users related to the current user when either a
18192     * user switch happens or when a new related user is started in the
18193     * background.
18194     */
18195    private void updateCurrentProfileIdsLocked() {
18196        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18197                mCurrentUserId, false /* enabledOnly */);
18198        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18199        for (int i = 0; i < currentProfileIds.length; i++) {
18200            currentProfileIds[i] = profiles.get(i).id;
18201        }
18202        mCurrentProfileIds = currentProfileIds;
18203
18204        synchronized (mUserProfileGroupIdsSelfLocked) {
18205            mUserProfileGroupIdsSelfLocked.clear();
18206            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18207            for (int i = 0; i < users.size(); i++) {
18208                UserInfo user = users.get(i);
18209                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18210                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18211                }
18212            }
18213        }
18214    }
18215
18216    private Set getProfileIdsLocked(int userId) {
18217        Set userIds = new HashSet<Integer>();
18218        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18219                userId, false /* enabledOnly */);
18220        for (UserInfo user : profiles) {
18221            userIds.add(Integer.valueOf(user.id));
18222        }
18223        return userIds;
18224    }
18225
18226    @Override
18227    public boolean switchUser(final int userId) {
18228        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18229        String userName;
18230        synchronized (this) {
18231            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18232            if (userInfo == null) {
18233                Slog.w(TAG, "No user info for user #" + userId);
18234                return false;
18235            }
18236            if (userInfo.isManagedProfile()) {
18237                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18238                return false;
18239            }
18240            userName = userInfo.name;
18241            mTargetUserId = userId;
18242        }
18243        mHandler.removeMessages(START_USER_SWITCH_MSG);
18244        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18245        return true;
18246    }
18247
18248    private void showUserSwitchDialog(int userId, String userName) {
18249        // The dialog will show and then initiate the user switch by calling startUserInForeground
18250        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18251                true /* above system */);
18252        d.show();
18253    }
18254
18255    private boolean startUser(final int userId, final boolean foreground) {
18256        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18257                != PackageManager.PERMISSION_GRANTED) {
18258            String msg = "Permission Denial: switchUser() from pid="
18259                    + Binder.getCallingPid()
18260                    + ", uid=" + Binder.getCallingUid()
18261                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18262            Slog.w(TAG, msg);
18263            throw new SecurityException(msg);
18264        }
18265
18266        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18267
18268        final long ident = Binder.clearCallingIdentity();
18269        try {
18270            synchronized (this) {
18271                final int oldUserId = mCurrentUserId;
18272                if (oldUserId == userId) {
18273                    return true;
18274                }
18275
18276                mStackSupervisor.setLockTaskModeLocked(null, false);
18277
18278                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18279                if (userInfo == null) {
18280                    Slog.w(TAG, "No user info for user #" + userId);
18281                    return false;
18282                }
18283                if (foreground && userInfo.isManagedProfile()) {
18284                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18285                    return false;
18286                }
18287
18288                if (foreground) {
18289                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18290                            R.anim.screen_user_enter);
18291                }
18292
18293                boolean needStart = false;
18294
18295                // If the user we are switching to is not currently started, then
18296                // we need to start it now.
18297                if (mStartedUsers.get(userId) == null) {
18298                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18299                    updateStartedUserArrayLocked();
18300                    needStart = true;
18301                }
18302
18303                final Integer userIdInt = Integer.valueOf(userId);
18304                mUserLru.remove(userIdInt);
18305                mUserLru.add(userIdInt);
18306
18307                if (foreground) {
18308                    mCurrentUserId = userId;
18309                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18310                    updateCurrentProfileIdsLocked();
18311                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18312                    // Once the internal notion of the active user has switched, we lock the device
18313                    // with the option to show the user switcher on the keyguard.
18314                    mWindowManager.lockNow(null);
18315                } else {
18316                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18317                    updateCurrentProfileIdsLocked();
18318                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18319                    mUserLru.remove(currentUserIdInt);
18320                    mUserLru.add(currentUserIdInt);
18321                }
18322
18323                final UserStartedState uss = mStartedUsers.get(userId);
18324
18325                // Make sure user is in the started state.  If it is currently
18326                // stopping, we need to knock that off.
18327                if (uss.mState == UserStartedState.STATE_STOPPING) {
18328                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18329                    // so we can just fairly silently bring the user back from
18330                    // the almost-dead.
18331                    uss.mState = UserStartedState.STATE_RUNNING;
18332                    updateStartedUserArrayLocked();
18333                    needStart = true;
18334                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18335                    // This means ACTION_SHUTDOWN has been sent, so we will
18336                    // need to treat this as a new boot of the user.
18337                    uss.mState = UserStartedState.STATE_BOOTING;
18338                    updateStartedUserArrayLocked();
18339                    needStart = true;
18340                }
18341
18342                if (uss.mState == UserStartedState.STATE_BOOTING) {
18343                    // Booting up a new user, need to tell system services about it.
18344                    // Note that this is on the same handler as scheduling of broadcasts,
18345                    // which is important because it needs to go first.
18346                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18347                }
18348
18349                if (foreground) {
18350                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18351                            oldUserId));
18352                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18353                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18354                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18355                            oldUserId, userId, uss));
18356                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18357                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18358                }
18359
18360                if (needStart) {
18361                    // Send USER_STARTED broadcast
18362                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18363                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18364                            | Intent.FLAG_RECEIVER_FOREGROUND);
18365                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18366                    broadcastIntentLocked(null, null, intent,
18367                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18368                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18369                }
18370
18371                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18372                    if (userId != UserHandle.USER_OWNER) {
18373                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18374                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18375                        broadcastIntentLocked(null, null, intent, null,
18376                                new IIntentReceiver.Stub() {
18377                                    public void performReceive(Intent intent, int resultCode,
18378                                            String data, Bundle extras, boolean ordered,
18379                                            boolean sticky, int sendingUser) {
18380                                        onUserInitialized(uss, foreground, oldUserId, userId);
18381                                    }
18382                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18383                                true, false, MY_PID, Process.SYSTEM_UID,
18384                                userId);
18385                        uss.initializing = true;
18386                    } else {
18387                        getUserManagerLocked().makeInitialized(userInfo.id);
18388                    }
18389                }
18390
18391                if (foreground) {
18392                    if (!uss.initializing) {
18393                        moveUserToForeground(uss, oldUserId, userId);
18394                    }
18395                } else {
18396                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18397                }
18398
18399                if (needStart) {
18400                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18401                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18402                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18403                    broadcastIntentLocked(null, null, intent,
18404                            null, new IIntentReceiver.Stub() {
18405                                @Override
18406                                public void performReceive(Intent intent, int resultCode, String data,
18407                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18408                                        throws RemoteException {
18409                                }
18410                            }, 0, null, null,
18411                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18412                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18413                }
18414            }
18415        } finally {
18416            Binder.restoreCallingIdentity(ident);
18417        }
18418
18419        return true;
18420    }
18421
18422    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18423        long ident = Binder.clearCallingIdentity();
18424        try {
18425            Intent intent;
18426            if (oldUserId >= 0) {
18427                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18428                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18429                int count = profiles.size();
18430                for (int i = 0; i < count; i++) {
18431                    int profileUserId = profiles.get(i).id;
18432                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18433                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18434                            | Intent.FLAG_RECEIVER_FOREGROUND);
18435                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18436                    broadcastIntentLocked(null, null, intent,
18437                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18438                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18439                }
18440            }
18441            if (newUserId >= 0) {
18442                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18443                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18444                int count = profiles.size();
18445                for (int i = 0; i < count; i++) {
18446                    int profileUserId = profiles.get(i).id;
18447                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18448                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18449                            | Intent.FLAG_RECEIVER_FOREGROUND);
18450                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18451                    broadcastIntentLocked(null, null, intent,
18452                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18453                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18454                }
18455                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18456                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18457                        | Intent.FLAG_RECEIVER_FOREGROUND);
18458                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18459                broadcastIntentLocked(null, null, intent,
18460                        null, null, 0, null, null,
18461                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18462                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18463            }
18464        } finally {
18465            Binder.restoreCallingIdentity(ident);
18466        }
18467    }
18468
18469    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18470            final int newUserId) {
18471        final int N = mUserSwitchObservers.beginBroadcast();
18472        if (N > 0) {
18473            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18474                int mCount = 0;
18475                @Override
18476                public void sendResult(Bundle data) throws RemoteException {
18477                    synchronized (ActivityManagerService.this) {
18478                        if (mCurUserSwitchCallback == this) {
18479                            mCount++;
18480                            if (mCount == N) {
18481                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18482                            }
18483                        }
18484                    }
18485                }
18486            };
18487            synchronized (this) {
18488                uss.switching = true;
18489                mCurUserSwitchCallback = callback;
18490            }
18491            for (int i=0; i<N; i++) {
18492                try {
18493                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18494                            newUserId, callback);
18495                } catch (RemoteException e) {
18496                }
18497            }
18498        } else {
18499            synchronized (this) {
18500                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18501            }
18502        }
18503        mUserSwitchObservers.finishBroadcast();
18504    }
18505
18506    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18507        synchronized (this) {
18508            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18509            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18510        }
18511    }
18512
18513    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18514        mCurUserSwitchCallback = null;
18515        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18516        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18517                oldUserId, newUserId, uss));
18518    }
18519
18520    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18521        synchronized (this) {
18522            if (foreground) {
18523                moveUserToForeground(uss, oldUserId, newUserId);
18524            }
18525        }
18526
18527        completeSwitchAndInitalize(uss, newUserId, true, false);
18528    }
18529
18530    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18531        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18532        if (homeInFront) {
18533            startHomeActivityLocked(newUserId);
18534        } else {
18535            mStackSupervisor.resumeTopActivitiesLocked();
18536        }
18537        EventLogTags.writeAmSwitchUser(newUserId);
18538        getUserManagerLocked().userForeground(newUserId);
18539        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18540    }
18541
18542    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18543        completeSwitchAndInitalize(uss, newUserId, false, true);
18544    }
18545
18546    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18547            boolean clearInitializing, boolean clearSwitching) {
18548        boolean unfrozen = false;
18549        synchronized (this) {
18550            if (clearInitializing) {
18551                uss.initializing = false;
18552                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18553            }
18554            if (clearSwitching) {
18555                uss.switching = false;
18556            }
18557            if (!uss.switching && !uss.initializing) {
18558                mWindowManager.stopFreezingScreen();
18559                unfrozen = true;
18560            }
18561        }
18562        if (unfrozen) {
18563            final int N = mUserSwitchObservers.beginBroadcast();
18564            for (int i=0; i<N; i++) {
18565                try {
18566                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18567                } catch (RemoteException e) {
18568                }
18569            }
18570            mUserSwitchObservers.finishBroadcast();
18571        }
18572    }
18573
18574    void scheduleStartProfilesLocked() {
18575        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18576            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18577                    DateUtils.SECOND_IN_MILLIS);
18578        }
18579    }
18580
18581    void startProfilesLocked() {
18582        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18583        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18584                mCurrentUserId, false /* enabledOnly */);
18585        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18586        for (UserInfo user : profiles) {
18587            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18588                    && user.id != mCurrentUserId) {
18589                toStart.add(user);
18590            }
18591        }
18592        final int n = toStart.size();
18593        int i = 0;
18594        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18595            startUserInBackground(toStart.get(i).id);
18596        }
18597        if (i < n) {
18598            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18599        }
18600    }
18601
18602    void finishUserBoot(UserStartedState uss) {
18603        synchronized (this) {
18604            if (uss.mState == UserStartedState.STATE_BOOTING
18605                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18606                uss.mState = UserStartedState.STATE_RUNNING;
18607                final int userId = uss.mHandle.getIdentifier();
18608                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18609                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18610                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18611                broadcastIntentLocked(null, null, intent,
18612                        null, null, 0, null, null,
18613                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18614                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18615            }
18616        }
18617    }
18618
18619    void finishUserSwitch(UserStartedState uss) {
18620        synchronized (this) {
18621            finishUserBoot(uss);
18622
18623            startProfilesLocked();
18624
18625            int num = mUserLru.size();
18626            int i = 0;
18627            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18628                Integer oldUserId = mUserLru.get(i);
18629                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18630                if (oldUss == null) {
18631                    // Shouldn't happen, but be sane if it does.
18632                    mUserLru.remove(i);
18633                    num--;
18634                    continue;
18635                }
18636                if (oldUss.mState == UserStartedState.STATE_STOPPING
18637                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18638                    // This user is already stopping, doesn't count.
18639                    num--;
18640                    i++;
18641                    continue;
18642                }
18643                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18644                    // Owner and current can't be stopped, but count as running.
18645                    i++;
18646                    continue;
18647                }
18648                // This is a user to be stopped.
18649                stopUserLocked(oldUserId, null);
18650                num--;
18651                i++;
18652            }
18653        }
18654    }
18655
18656    @Override
18657    public int stopUser(final int userId, final IStopUserCallback callback) {
18658        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18659                != PackageManager.PERMISSION_GRANTED) {
18660            String msg = "Permission Denial: switchUser() from pid="
18661                    + Binder.getCallingPid()
18662                    + ", uid=" + Binder.getCallingUid()
18663                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18664            Slog.w(TAG, msg);
18665            throw new SecurityException(msg);
18666        }
18667        if (userId <= 0) {
18668            throw new IllegalArgumentException("Can't stop primary user " + userId);
18669        }
18670        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18671        synchronized (this) {
18672            return stopUserLocked(userId, callback);
18673        }
18674    }
18675
18676    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18677        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18678        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18679            return ActivityManager.USER_OP_IS_CURRENT;
18680        }
18681
18682        final UserStartedState uss = mStartedUsers.get(userId);
18683        if (uss == null) {
18684            // User is not started, nothing to do...  but we do need to
18685            // callback if requested.
18686            if (callback != null) {
18687                mHandler.post(new Runnable() {
18688                    @Override
18689                    public void run() {
18690                        try {
18691                            callback.userStopped(userId);
18692                        } catch (RemoteException e) {
18693                        }
18694                    }
18695                });
18696            }
18697            return ActivityManager.USER_OP_SUCCESS;
18698        }
18699
18700        if (callback != null) {
18701            uss.mStopCallbacks.add(callback);
18702        }
18703
18704        if (uss.mState != UserStartedState.STATE_STOPPING
18705                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18706            uss.mState = UserStartedState.STATE_STOPPING;
18707            updateStartedUserArrayLocked();
18708
18709            long ident = Binder.clearCallingIdentity();
18710            try {
18711                // We are going to broadcast ACTION_USER_STOPPING and then
18712                // once that is done send a final ACTION_SHUTDOWN and then
18713                // stop the user.
18714                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18715                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18716                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18717                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18718                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18719                // This is the result receiver for the final shutdown broadcast.
18720                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18721                    @Override
18722                    public void performReceive(Intent intent, int resultCode, String data,
18723                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18724                        finishUserStop(uss);
18725                    }
18726                };
18727                // This is the result receiver for the initial stopping broadcast.
18728                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18729                    @Override
18730                    public void performReceive(Intent intent, int resultCode, String data,
18731                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18732                        // On to the next.
18733                        synchronized (ActivityManagerService.this) {
18734                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18735                                // Whoops, we are being started back up.  Abort, abort!
18736                                return;
18737                            }
18738                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18739                        }
18740                        mBatteryStatsService.noteEvent(
18741                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18742                                Integer.toString(userId), userId);
18743                        mSystemServiceManager.stopUser(userId);
18744                        broadcastIntentLocked(null, null, shutdownIntent,
18745                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18746                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18747                    }
18748                };
18749                // Kick things off.
18750                broadcastIntentLocked(null, null, stoppingIntent,
18751                        null, stoppingReceiver, 0, null, null,
18752                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18753                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18754            } finally {
18755                Binder.restoreCallingIdentity(ident);
18756            }
18757        }
18758
18759        return ActivityManager.USER_OP_SUCCESS;
18760    }
18761
18762    void finishUserStop(UserStartedState uss) {
18763        final int userId = uss.mHandle.getIdentifier();
18764        boolean stopped;
18765        ArrayList<IStopUserCallback> callbacks;
18766        synchronized (this) {
18767            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18768            if (mStartedUsers.get(userId) != uss) {
18769                stopped = false;
18770            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18771                stopped = false;
18772            } else {
18773                stopped = true;
18774                // User can no longer run.
18775                mStartedUsers.remove(userId);
18776                mUserLru.remove(Integer.valueOf(userId));
18777                updateStartedUserArrayLocked();
18778
18779                // Clean up all state and processes associated with the user.
18780                // Kill all the processes for the user.
18781                forceStopUserLocked(userId, "finish user");
18782            }
18783
18784            // Explicitly remove the old information in mRecentTasks.
18785            removeRecentTasksForUserLocked(userId);
18786        }
18787
18788        for (int i=0; i<callbacks.size(); i++) {
18789            try {
18790                if (stopped) callbacks.get(i).userStopped(userId);
18791                else callbacks.get(i).userStopAborted(userId);
18792            } catch (RemoteException e) {
18793            }
18794        }
18795
18796        if (stopped) {
18797            mSystemServiceManager.cleanupUser(userId);
18798            synchronized (this) {
18799                mStackSupervisor.removeUserLocked(userId);
18800            }
18801        }
18802    }
18803
18804    @Override
18805    public UserInfo getCurrentUser() {
18806        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18807                != PackageManager.PERMISSION_GRANTED) && (
18808                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18809                != PackageManager.PERMISSION_GRANTED)) {
18810            String msg = "Permission Denial: getCurrentUser() from pid="
18811                    + Binder.getCallingPid()
18812                    + ", uid=" + Binder.getCallingUid()
18813                    + " requires " + INTERACT_ACROSS_USERS;
18814            Slog.w(TAG, msg);
18815            throw new SecurityException(msg);
18816        }
18817        synchronized (this) {
18818            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18819            return getUserManagerLocked().getUserInfo(userId);
18820        }
18821    }
18822
18823    int getCurrentUserIdLocked() {
18824        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18825    }
18826
18827    @Override
18828    public boolean isUserRunning(int userId, boolean orStopped) {
18829        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18830                != PackageManager.PERMISSION_GRANTED) {
18831            String msg = "Permission Denial: isUserRunning() from pid="
18832                    + Binder.getCallingPid()
18833                    + ", uid=" + Binder.getCallingUid()
18834                    + " requires " + INTERACT_ACROSS_USERS;
18835            Slog.w(TAG, msg);
18836            throw new SecurityException(msg);
18837        }
18838        synchronized (this) {
18839            return isUserRunningLocked(userId, orStopped);
18840        }
18841    }
18842
18843    boolean isUserRunningLocked(int userId, boolean orStopped) {
18844        UserStartedState state = mStartedUsers.get(userId);
18845        if (state == null) {
18846            return false;
18847        }
18848        if (orStopped) {
18849            return true;
18850        }
18851        return state.mState != UserStartedState.STATE_STOPPING
18852                && state.mState != UserStartedState.STATE_SHUTDOWN;
18853    }
18854
18855    @Override
18856    public int[] getRunningUserIds() {
18857        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18858                != PackageManager.PERMISSION_GRANTED) {
18859            String msg = "Permission Denial: isUserRunning() from pid="
18860                    + Binder.getCallingPid()
18861                    + ", uid=" + Binder.getCallingUid()
18862                    + " requires " + INTERACT_ACROSS_USERS;
18863            Slog.w(TAG, msg);
18864            throw new SecurityException(msg);
18865        }
18866        synchronized (this) {
18867            return mStartedUserArray;
18868        }
18869    }
18870
18871    private void updateStartedUserArrayLocked() {
18872        int num = 0;
18873        for (int i=0; i<mStartedUsers.size();  i++) {
18874            UserStartedState uss = mStartedUsers.valueAt(i);
18875            // This list does not include stopping users.
18876            if (uss.mState != UserStartedState.STATE_STOPPING
18877                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18878                num++;
18879            }
18880        }
18881        mStartedUserArray = new int[num];
18882        num = 0;
18883        for (int i=0; i<mStartedUsers.size();  i++) {
18884            UserStartedState uss = mStartedUsers.valueAt(i);
18885            if (uss.mState != UserStartedState.STATE_STOPPING
18886                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18887                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18888                num++;
18889            }
18890        }
18891    }
18892
18893    @Override
18894    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18895        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18896                != PackageManager.PERMISSION_GRANTED) {
18897            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18898                    + Binder.getCallingPid()
18899                    + ", uid=" + Binder.getCallingUid()
18900                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18901            Slog.w(TAG, msg);
18902            throw new SecurityException(msg);
18903        }
18904
18905        mUserSwitchObservers.register(observer);
18906    }
18907
18908    @Override
18909    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18910        mUserSwitchObservers.unregister(observer);
18911    }
18912
18913    private boolean userExists(int userId) {
18914        if (userId == 0) {
18915            return true;
18916        }
18917        UserManagerService ums = getUserManagerLocked();
18918        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18919    }
18920
18921    int[] getUsersLocked() {
18922        UserManagerService ums = getUserManagerLocked();
18923        return ums != null ? ums.getUserIds() : new int[] { 0 };
18924    }
18925
18926    UserManagerService getUserManagerLocked() {
18927        if (mUserManager == null) {
18928            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18929            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18930        }
18931        return mUserManager;
18932    }
18933
18934    private int applyUserId(int uid, int userId) {
18935        return UserHandle.getUid(userId, uid);
18936    }
18937
18938    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18939        if (info == null) return null;
18940        ApplicationInfo newInfo = new ApplicationInfo(info);
18941        newInfo.uid = applyUserId(info.uid, userId);
18942        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18943                + info.packageName;
18944        return newInfo;
18945    }
18946
18947    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18948        if (aInfo == null
18949                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18950            return aInfo;
18951        }
18952
18953        ActivityInfo info = new ActivityInfo(aInfo);
18954        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18955        return info;
18956    }
18957
18958    private final class LocalService extends ActivityManagerInternal {
18959        @Override
18960        public void goingToSleep() {
18961            ActivityManagerService.this.goingToSleep();
18962        }
18963
18964        @Override
18965        public void wakingUp() {
18966            ActivityManagerService.this.wakingUp();
18967        }
18968
18969        @Override
18970        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18971                String processName, String abiOverride, int uid, Runnable crashHandler) {
18972            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18973                    processName, abiOverride, uid, crashHandler);
18974        }
18975    }
18976
18977    /**
18978     * An implementation of IAppTask, that allows an app to manage its own tasks via
18979     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18980     * only the process that calls getAppTasks() can call the AppTask methods.
18981     */
18982    class AppTaskImpl extends IAppTask.Stub {
18983        private int mTaskId;
18984        private int mCallingUid;
18985
18986        public AppTaskImpl(int taskId, int callingUid) {
18987            mTaskId = taskId;
18988            mCallingUid = callingUid;
18989        }
18990
18991        private void checkCaller() {
18992            if (mCallingUid != Binder.getCallingUid()) {
18993                throw new SecurityException("Caller " + mCallingUid
18994                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18995            }
18996        }
18997
18998        @Override
18999        public void finishAndRemoveTask() {
19000            checkCaller();
19001
19002            synchronized (ActivityManagerService.this) {
19003                long origId = Binder.clearCallingIdentity();
19004                try {
19005                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19006                    if (tr == null) {
19007                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19008                    }
19009                    // Only kill the process if we are not a new document
19010                    int flags = tr.getBaseIntent().getFlags();
19011                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19012                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19013                    removeTaskByIdLocked(mTaskId,
19014                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19015                } finally {
19016                    Binder.restoreCallingIdentity(origId);
19017                }
19018            }
19019        }
19020
19021        @Override
19022        public ActivityManager.RecentTaskInfo getTaskInfo() {
19023            checkCaller();
19024
19025            synchronized (ActivityManagerService.this) {
19026                long origId = Binder.clearCallingIdentity();
19027                try {
19028                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19029                    if (tr == null) {
19030                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19031                    }
19032                    return createRecentTaskInfoFromTaskRecord(tr);
19033                } finally {
19034                    Binder.restoreCallingIdentity(origId);
19035                }
19036            }
19037        }
19038
19039        @Override
19040        public void moveToFront() {
19041            checkCaller();
19042
19043            final TaskRecord tr;
19044            synchronized (ActivityManagerService.this) {
19045                tr = recentTaskForIdLocked(mTaskId);
19046                if (tr == null) {
19047                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19048                }
19049                if (tr.getRootActivity() != null) {
19050                    moveTaskToFrontLocked(tr.taskId, 0, null);
19051                    return;
19052                }
19053            }
19054
19055            startActivityFromRecentsInner(tr.taskId, null);
19056        }
19057
19058        @Override
19059        public int startActivity(IBinder whoThread, String callingPackage,
19060                Intent intent, String resolvedType, Bundle options) {
19061            checkCaller();
19062
19063            int callingUser = UserHandle.getCallingUserId();
19064            TaskRecord tr;
19065            IApplicationThread appThread;
19066            synchronized (ActivityManagerService.this) {
19067                tr = recentTaskForIdLocked(mTaskId);
19068                if (tr == null) {
19069                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19070                }
19071                appThread = ApplicationThreadNative.asInterface(whoThread);
19072                if (appThread == null) {
19073                    throw new IllegalArgumentException("Bad app thread " + appThread);
19074                }
19075            }
19076            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19077                    resolvedType, null, null, null, null, 0, 0, null, null,
19078                    null, options, callingUser, null, tr);
19079        }
19080
19081        @Override
19082        public void setExcludeFromRecents(boolean exclude) {
19083            checkCaller();
19084
19085            synchronized (ActivityManagerService.this) {
19086                long origId = Binder.clearCallingIdentity();
19087                try {
19088                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19089                    if (tr == null) {
19090                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19091                    }
19092                    Intent intent = tr.getBaseIntent();
19093                    if (exclude) {
19094                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19095                    } else {
19096                        intent.setFlags(intent.getFlags()
19097                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19098                    }
19099                } finally {
19100                    Binder.restoreCallingIdentity(origId);
19101                }
19102            }
19103        }
19104    }
19105}
19106