ActivityManagerService.java revision f839b4fcb6b179529585765517895a8c90fe315b
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 ENABLE_SCREEN_AFTER_BOOT_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 ENABLE_SCREEN_AFTER_BOOT_MSG: {
1881                enableScreenAfterBoot();
1882                break;
1883            }
1884            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1885                try {
1886                    Locale l = (Locale) msg.obj;
1887                    IBinder service = ServiceManager.getService("mount");
1888                    IMountService mountService = IMountService.Stub.asInterface(service);
1889                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1890                    mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1891                } catch (RemoteException e) {
1892                    Log.e(TAG, "Error storing locale for decryption UI", e);
1893                }
1894                break;
1895            }
1896            }
1897        }
1898    };
1899
1900    static final int COLLECT_PSS_BG_MSG = 1;
1901
1902    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1903        @Override
1904        public void handleMessage(Message msg) {
1905            switch (msg.what) {
1906            case COLLECT_PSS_BG_MSG: {
1907                long start = SystemClock.uptimeMillis();
1908                MemInfoReader memInfo = null;
1909                synchronized (ActivityManagerService.this) {
1910                    if (mFullPssPending) {
1911                        mFullPssPending = false;
1912                        memInfo = new MemInfoReader();
1913                    }
1914                }
1915                if (memInfo != null) {
1916                    updateCpuStatsNow();
1917                    long nativeTotalPss = 0;
1918                    synchronized (mProcessCpuTracker) {
1919                        final int N = mProcessCpuTracker.countStats();
1920                        for (int j=0; j<N; j++) {
1921                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1922                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1923                                // This is definitely an application process; skip it.
1924                                continue;
1925                            }
1926                            synchronized (mPidsSelfLocked) {
1927                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1928                                    // This is one of our own processes; skip it.
1929                                    continue;
1930                                }
1931                            }
1932                            nativeTotalPss += Debug.getPss(st.pid, null);
1933                        }
1934                    }
1935                    memInfo.readMemInfo();
1936                    synchronized (ActivityManagerService.this) {
1937                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1938                                + (SystemClock.uptimeMillis()-start) + "ms");
1939                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1940                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1941                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1942                                        +memInfo.getSlabSizeKb(),
1943                                nativeTotalPss);
1944                    }
1945                }
1946
1947                int i=0, num=0;
1948                long[] tmp = new long[1];
1949                do {
1950                    ProcessRecord proc;
1951                    int procState;
1952                    int pid;
1953                    synchronized (ActivityManagerService.this) {
1954                        if (i >= mPendingPssProcesses.size()) {
1955                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1956                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1957                            mPendingPssProcesses.clear();
1958                            return;
1959                        }
1960                        proc = mPendingPssProcesses.get(i);
1961                        procState = proc.pssProcState;
1962                        if (proc.thread != null && procState == proc.setProcState) {
1963                            pid = proc.pid;
1964                        } else {
1965                            proc = null;
1966                            pid = 0;
1967                        }
1968                        i++;
1969                    }
1970                    if (proc != null) {
1971                        long pss = Debug.getPss(pid, tmp);
1972                        synchronized (ActivityManagerService.this) {
1973                            if (proc.thread != null && proc.setProcState == procState
1974                                    && proc.pid == pid) {
1975                                num++;
1976                                proc.lastPssTime = SystemClock.uptimeMillis();
1977                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1978                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1979                                        + ": " + pss + " lastPss=" + proc.lastPss
1980                                        + " state=" + ProcessList.makeProcStateString(procState));
1981                                if (proc.initialIdlePss == 0) {
1982                                    proc.initialIdlePss = pss;
1983                                }
1984                                proc.lastPss = pss;
1985                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1986                                    proc.lastCachedPss = pss;
1987                                }
1988                            }
1989                        }
1990                    }
1991                } while (true);
1992            }
1993            }
1994        }
1995    };
1996
1997    /**
1998     * Monitor for package changes and update our internal state.
1999     */
2000    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2001        @Override
2002        public void onPackageRemoved(String packageName, int uid) {
2003            // Remove all tasks with activities in the specified package from the list of recent tasks
2004            final int eventUserId = getChangingUserId();
2005            synchronized (ActivityManagerService.this) {
2006                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2007                    TaskRecord tr = mRecentTasks.get(i);
2008                    if (tr.userId != eventUserId) continue;
2009
2010                    ComponentName cn = tr.intent.getComponent();
2011                    if (cn != null && cn.getPackageName().equals(packageName)) {
2012                        // If the package name matches, remove the task and kill the process
2013                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2014                    }
2015                }
2016            }
2017        }
2018
2019        @Override
2020        public boolean onPackageChanged(String packageName, int uid, String[] components) {
2021            onPackageModified(packageName);
2022            return true;
2023        }
2024
2025        @Override
2026        public void onPackageModified(String packageName) {
2027            final int eventUserId = getChangingUserId();
2028            final PackageManager pm = mContext.getPackageManager();
2029            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2030                    new ArrayList<Pair<Intent, Integer>>();
2031            final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2032            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2033            // Copy the list of recent tasks so that we don't hold onto the lock on
2034            // ActivityManagerService for long periods while checking if components exist.
2035            synchronized (ActivityManagerService.this) {
2036                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2037                    TaskRecord tr = mRecentTasks.get(i);
2038                    if (tr.userId != eventUserId) continue;
2039
2040                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2041                }
2042            }
2043            // Check the recent tasks and filter out all tasks with components that no longer exist.
2044            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2045                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2046                ComponentName cn = p.first.getComponent();
2047                if (cn != null && cn.getPackageName().equals(packageName)) {
2048                    if (componentsKnownToExist.contains(cn)) {
2049                        // If we know that the component still exists in the package, then skip
2050                        continue;
2051                    }
2052                    try {
2053                        ActivityInfo info = pm.getActivityInfo(cn, eventUserId);
2054                        if (info != null && info.isEnabled()) {
2055                            componentsKnownToExist.add(cn);
2056                        } else {
2057                            tasksToRemove.add(p.second);
2058                        }
2059                    } catch (Exception e) {}
2060                }
2061            }
2062            // Prune all the tasks with removed components from the list of recent tasks
2063            synchronized (ActivityManagerService.this) {
2064                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2065                    // Remove the task but don't kill the process (since other components in that
2066                    // package may still be running and in the background)
2067                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2068                }
2069            }
2070        }
2071
2072        @Override
2073        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2074            // Force stop the specified packages
2075            int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2076            if (packages != null) {
2077                for (String pkg : packages) {
2078                    synchronized (ActivityManagerService.this) {
2079                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2080                                userId, "finished booting")) {
2081                            return true;
2082                        }
2083                    }
2084                }
2085            }
2086            return false;
2087        }
2088    };
2089
2090    public void setSystemProcess() {
2091        try {
2092            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2093            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2094            ServiceManager.addService("meminfo", new MemBinder(this));
2095            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2096            ServiceManager.addService("dbinfo", new DbBinder(this));
2097            if (MONITOR_CPU_USAGE) {
2098                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2099            }
2100            ServiceManager.addService("permission", new PermissionController(this));
2101
2102            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2103                    "android", STOCK_PM_FLAGS);
2104            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2105
2106            synchronized (this) {
2107                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2108                app.persistent = true;
2109                app.pid = MY_PID;
2110                app.maxAdj = ProcessList.SYSTEM_ADJ;
2111                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2112                mProcessNames.put(app.processName, app.uid, app);
2113                synchronized (mPidsSelfLocked) {
2114                    mPidsSelfLocked.put(app.pid, app);
2115                }
2116                updateLruProcessLocked(app, false, null);
2117                updateOomAdjLocked();
2118            }
2119        } catch (PackageManager.NameNotFoundException e) {
2120            throw new RuntimeException(
2121                    "Unable to find android system package", e);
2122        }
2123    }
2124
2125    public void setWindowManager(WindowManagerService wm) {
2126        mWindowManager = wm;
2127        mStackSupervisor.setWindowManager(wm);
2128    }
2129
2130    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2131        mUsageStatsService = usageStatsManager;
2132    }
2133
2134    public void startObservingNativeCrashes() {
2135        final NativeCrashListener ncl = new NativeCrashListener(this);
2136        ncl.start();
2137    }
2138
2139    public IAppOpsService getAppOpsService() {
2140        return mAppOpsService;
2141    }
2142
2143    static class MemBinder extends Binder {
2144        ActivityManagerService mActivityManagerService;
2145        MemBinder(ActivityManagerService activityManagerService) {
2146            mActivityManagerService = activityManagerService;
2147        }
2148
2149        @Override
2150        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2151            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2152                    != PackageManager.PERMISSION_GRANTED) {
2153                pw.println("Permission Denial: can't dump meminfo from from pid="
2154                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2155                        + " without permission " + android.Manifest.permission.DUMP);
2156                return;
2157            }
2158
2159            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2160        }
2161    }
2162
2163    static class GraphicsBinder extends Binder {
2164        ActivityManagerService mActivityManagerService;
2165        GraphicsBinder(ActivityManagerService activityManagerService) {
2166            mActivityManagerService = activityManagerService;
2167        }
2168
2169        @Override
2170        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2171            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2172                    != PackageManager.PERMISSION_GRANTED) {
2173                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2174                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2175                        + " without permission " + android.Manifest.permission.DUMP);
2176                return;
2177            }
2178
2179            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2180        }
2181    }
2182
2183    static class DbBinder extends Binder {
2184        ActivityManagerService mActivityManagerService;
2185        DbBinder(ActivityManagerService activityManagerService) {
2186            mActivityManagerService = activityManagerService;
2187        }
2188
2189        @Override
2190        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2191            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2192                    != PackageManager.PERMISSION_GRANTED) {
2193                pw.println("Permission Denial: can't dump dbinfo from from pid="
2194                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2195                        + " without permission " + android.Manifest.permission.DUMP);
2196                return;
2197            }
2198
2199            mActivityManagerService.dumpDbInfo(fd, pw, args);
2200        }
2201    }
2202
2203    static class CpuBinder extends Binder {
2204        ActivityManagerService mActivityManagerService;
2205        CpuBinder(ActivityManagerService activityManagerService) {
2206            mActivityManagerService = activityManagerService;
2207        }
2208
2209        @Override
2210        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2211            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2212                    != PackageManager.PERMISSION_GRANTED) {
2213                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2214                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2215                        + " without permission " + android.Manifest.permission.DUMP);
2216                return;
2217            }
2218
2219            synchronized (mActivityManagerService.mProcessCpuTracker) {
2220                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2221                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2222                        SystemClock.uptimeMillis()));
2223            }
2224        }
2225    }
2226
2227    public static final class Lifecycle extends SystemService {
2228        private final ActivityManagerService mService;
2229
2230        public Lifecycle(Context context) {
2231            super(context);
2232            mService = new ActivityManagerService(context);
2233        }
2234
2235        @Override
2236        public void onStart() {
2237            mService.start();
2238        }
2239
2240        public ActivityManagerService getService() {
2241            return mService;
2242        }
2243    }
2244
2245    // Note: This method is invoked on the main thread but may need to attach various
2246    // handlers to other threads.  So take care to be explicit about the looper.
2247    public ActivityManagerService(Context systemContext) {
2248        mContext = systemContext;
2249        mFactoryTest = FactoryTest.getMode();
2250        mSystemThread = ActivityThread.currentActivityThread();
2251
2252        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2253
2254        mHandlerThread = new ServiceThread(TAG,
2255                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2256        mHandlerThread.start();
2257        mHandler = new MainHandler(mHandlerThread.getLooper());
2258
2259        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2260                "foreground", BROADCAST_FG_TIMEOUT, false);
2261        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2262                "background", BROADCAST_BG_TIMEOUT, true);
2263        mBroadcastQueues[0] = mFgBroadcastQueue;
2264        mBroadcastQueues[1] = mBgBroadcastQueue;
2265
2266        mServices = new ActiveServices(this);
2267        mProviderMap = new ProviderMap(this);
2268
2269        // TODO: Move creation of battery stats service outside of activity manager service.
2270        File dataDir = Environment.getDataDirectory();
2271        File systemDir = new File(dataDir, "system");
2272        systemDir.mkdirs();
2273        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2274        mBatteryStatsService.getActiveStatistics().readLocked();
2275        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2276        mOnBattery = DEBUG_POWER ? true
2277                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2278        mBatteryStatsService.getActiveStatistics().setCallback(this);
2279
2280        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2281
2282        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2283
2284        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2285
2286        // User 0 is the first and only user that runs at boot.
2287        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2288        mUserLru.add(Integer.valueOf(0));
2289        updateStartedUserArrayLocked();
2290
2291        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2292            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2293
2294        mConfiguration.setToDefaults();
2295        mConfiguration.setLocale(Locale.getDefault());
2296
2297        mConfigurationSeq = mConfiguration.seq = 1;
2298        mProcessCpuTracker.init();
2299
2300        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2301        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2302        mStackSupervisor = new ActivityStackSupervisor(this);
2303        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2304
2305        mProcessCpuThread = new Thread("CpuTracker") {
2306            @Override
2307            public void run() {
2308                while (true) {
2309                    try {
2310                        try {
2311                            synchronized(this) {
2312                                final long now = SystemClock.uptimeMillis();
2313                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2314                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2315                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2316                                //        + ", write delay=" + nextWriteDelay);
2317                                if (nextWriteDelay < nextCpuDelay) {
2318                                    nextCpuDelay = nextWriteDelay;
2319                                }
2320                                if (nextCpuDelay > 0) {
2321                                    mProcessCpuMutexFree.set(true);
2322                                    this.wait(nextCpuDelay);
2323                                }
2324                            }
2325                        } catch (InterruptedException e) {
2326                        }
2327                        updateCpuStatsNow();
2328                    } catch (Exception e) {
2329                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2330                    }
2331                }
2332            }
2333        };
2334
2335        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2336
2337        Watchdog.getInstance().addMonitor(this);
2338        Watchdog.getInstance().addThread(mHandler);
2339    }
2340
2341    public void setSystemServiceManager(SystemServiceManager mgr) {
2342        mSystemServiceManager = mgr;
2343    }
2344
2345    private void start() {
2346        Process.removeAllProcessGroups();
2347        mProcessCpuThread.start();
2348
2349        mBatteryStatsService.publish(mContext);
2350        mAppOpsService.publish(mContext);
2351        Slog.d("AppOps", "AppOpsService published");
2352        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2353    }
2354
2355    public void initPowerManagement() {
2356        mStackSupervisor.initPowerManagement();
2357        mBatteryStatsService.initPowerManagement();
2358    }
2359
2360    @Override
2361    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2362            throws RemoteException {
2363        if (code == SYSPROPS_TRANSACTION) {
2364            // We need to tell all apps about the system property change.
2365            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2366            synchronized(this) {
2367                final int NP = mProcessNames.getMap().size();
2368                for (int ip=0; ip<NP; ip++) {
2369                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2370                    final int NA = apps.size();
2371                    for (int ia=0; ia<NA; ia++) {
2372                        ProcessRecord app = apps.valueAt(ia);
2373                        if (app.thread != null) {
2374                            procs.add(app.thread.asBinder());
2375                        }
2376                    }
2377                }
2378            }
2379
2380            int N = procs.size();
2381            for (int i=0; i<N; i++) {
2382                Parcel data2 = Parcel.obtain();
2383                try {
2384                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2385                } catch (RemoteException e) {
2386                }
2387                data2.recycle();
2388            }
2389        }
2390        try {
2391            return super.onTransact(code, data, reply, flags);
2392        } catch (RuntimeException e) {
2393            // The activity manager only throws security exceptions, so let's
2394            // log all others.
2395            if (!(e instanceof SecurityException)) {
2396                Slog.wtf(TAG, "Activity Manager Crash", e);
2397            }
2398            throw e;
2399        }
2400    }
2401
2402    void updateCpuStats() {
2403        final long now = SystemClock.uptimeMillis();
2404        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2405            return;
2406        }
2407        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2408            synchronized (mProcessCpuThread) {
2409                mProcessCpuThread.notify();
2410            }
2411        }
2412    }
2413
2414    void updateCpuStatsNow() {
2415        synchronized (mProcessCpuTracker) {
2416            mProcessCpuMutexFree.set(false);
2417            final long now = SystemClock.uptimeMillis();
2418            boolean haveNewCpuStats = false;
2419
2420            if (MONITOR_CPU_USAGE &&
2421                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2422                mLastCpuTime.set(now);
2423                haveNewCpuStats = true;
2424                mProcessCpuTracker.update();
2425                //Slog.i(TAG, mProcessCpu.printCurrentState());
2426                //Slog.i(TAG, "Total CPU usage: "
2427                //        + mProcessCpu.getTotalCpuPercent() + "%");
2428
2429                // Slog the cpu usage if the property is set.
2430                if ("true".equals(SystemProperties.get("events.cpu"))) {
2431                    int user = mProcessCpuTracker.getLastUserTime();
2432                    int system = mProcessCpuTracker.getLastSystemTime();
2433                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2434                    int irq = mProcessCpuTracker.getLastIrqTime();
2435                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2436                    int idle = mProcessCpuTracker.getLastIdleTime();
2437
2438                    int total = user + system + iowait + irq + softIrq + idle;
2439                    if (total == 0) total = 1;
2440
2441                    EventLog.writeEvent(EventLogTags.CPU,
2442                            ((user+system+iowait+irq+softIrq) * 100) / total,
2443                            (user * 100) / total,
2444                            (system * 100) / total,
2445                            (iowait * 100) / total,
2446                            (irq * 100) / total,
2447                            (softIrq * 100) / total);
2448                }
2449            }
2450
2451            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2452            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2453            synchronized(bstats) {
2454                synchronized(mPidsSelfLocked) {
2455                    if (haveNewCpuStats) {
2456                        if (mOnBattery) {
2457                            int perc = bstats.startAddingCpuLocked();
2458                            int totalUTime = 0;
2459                            int totalSTime = 0;
2460                            final int N = mProcessCpuTracker.countStats();
2461                            for (int i=0; i<N; i++) {
2462                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2463                                if (!st.working) {
2464                                    continue;
2465                                }
2466                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2467                                int otherUTime = (st.rel_utime*perc)/100;
2468                                int otherSTime = (st.rel_stime*perc)/100;
2469                                totalUTime += otherUTime;
2470                                totalSTime += otherSTime;
2471                                if (pr != null) {
2472                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2473                                    if (ps == null || !ps.isActive()) {
2474                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2475                                                pr.info.uid, pr.processName);
2476                                    }
2477                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2478                                            st.rel_stime-otherSTime);
2479                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2480                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2481                                } else {
2482                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2483                                    if (ps == null || !ps.isActive()) {
2484                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2485                                                bstats.mapUid(st.uid), st.name);
2486                                    }
2487                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2488                                            st.rel_stime-otherSTime);
2489                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2490                                }
2491                            }
2492                            bstats.finishAddingCpuLocked(perc, totalUTime,
2493                                    totalSTime, cpuSpeedTimes);
2494                        }
2495                    }
2496                }
2497
2498                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2499                    mLastWriteTime = now;
2500                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2501                }
2502            }
2503        }
2504    }
2505
2506    @Override
2507    public void batteryNeedsCpuUpdate() {
2508        updateCpuStatsNow();
2509    }
2510
2511    @Override
2512    public void batteryPowerChanged(boolean onBattery) {
2513        // When plugging in, update the CPU stats first before changing
2514        // the plug state.
2515        updateCpuStatsNow();
2516        synchronized (this) {
2517            synchronized(mPidsSelfLocked) {
2518                mOnBattery = DEBUG_POWER ? true : onBattery;
2519            }
2520        }
2521    }
2522
2523    /**
2524     * Initialize the application bind args. These are passed to each
2525     * process when the bindApplication() IPC is sent to the process. They're
2526     * lazily setup to make sure the services are running when they're asked for.
2527     */
2528    private HashMap<String, IBinder> getCommonServicesLocked() {
2529        if (mAppBindArgs == null) {
2530            mAppBindArgs = new HashMap<String, IBinder>();
2531
2532            // Setup the application init args
2533            mAppBindArgs.put("package", ServiceManager.getService("package"));
2534            mAppBindArgs.put("window", ServiceManager.getService("window"));
2535            mAppBindArgs.put(Context.ALARM_SERVICE,
2536                    ServiceManager.getService(Context.ALARM_SERVICE));
2537        }
2538        return mAppBindArgs;
2539    }
2540
2541    final void setFocusedActivityLocked(ActivityRecord r) {
2542        if (mFocusedActivity != r) {
2543            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2544            mFocusedActivity = r;
2545            if (r.task != null && r.task.voiceInteractor != null) {
2546                startRunningVoiceLocked();
2547            } else {
2548                finishRunningVoiceLocked();
2549            }
2550            mStackSupervisor.setFocusedStack(r);
2551            if (r != null) {
2552                mWindowManager.setFocusedApp(r.appToken, true);
2553            }
2554            applyUpdateLockStateLocked(r);
2555        }
2556    }
2557
2558    final void clearFocusedActivity(ActivityRecord r) {
2559        if (mFocusedActivity == r) {
2560            mFocusedActivity = null;
2561        }
2562    }
2563
2564    @Override
2565    public void setFocusedStack(int stackId) {
2566        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2567        synchronized (ActivityManagerService.this) {
2568            ActivityStack stack = mStackSupervisor.getStack(stackId);
2569            if (stack != null) {
2570                ActivityRecord r = stack.topRunningActivityLocked(null);
2571                if (r != null) {
2572                    setFocusedActivityLocked(r);
2573                }
2574            }
2575        }
2576    }
2577
2578    @Override
2579    public void notifyActivityDrawn(IBinder token) {
2580        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2581        synchronized (this) {
2582            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2583            if (r != null) {
2584                r.task.stack.notifyActivityDrawnLocked(r);
2585            }
2586        }
2587    }
2588
2589    final void applyUpdateLockStateLocked(ActivityRecord r) {
2590        // Modifications to the UpdateLock state are done on our handler, outside
2591        // the activity manager's locks.  The new state is determined based on the
2592        // state *now* of the relevant activity record.  The object is passed to
2593        // the handler solely for logging detail, not to be consulted/modified.
2594        final boolean nextState = r != null && r.immersive;
2595        mHandler.sendMessage(
2596                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2597    }
2598
2599    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2600        Message msg = Message.obtain();
2601        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2602        msg.obj = r.task.askedCompatMode ? null : r;
2603        mHandler.sendMessage(msg);
2604    }
2605
2606    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2607            String what, Object obj, ProcessRecord srcApp) {
2608        app.lastActivityTime = now;
2609
2610        if (app.activities.size() > 0) {
2611            // Don't want to touch dependent processes that are hosting activities.
2612            return index;
2613        }
2614
2615        int lrui = mLruProcesses.lastIndexOf(app);
2616        if (lrui < 0) {
2617            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2618                    + what + " " + obj + " from " + srcApp);
2619            return index;
2620        }
2621
2622        if (lrui >= index) {
2623            // Don't want to cause this to move dependent processes *back* in the
2624            // list as if they were less frequently used.
2625            return index;
2626        }
2627
2628        if (lrui >= mLruProcessActivityStart) {
2629            // Don't want to touch dependent processes that are hosting activities.
2630            return index;
2631        }
2632
2633        mLruProcesses.remove(lrui);
2634        if (index > 0) {
2635            index--;
2636        }
2637        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2638                + " in LRU list: " + app);
2639        mLruProcesses.add(index, app);
2640        return index;
2641    }
2642
2643    final void removeLruProcessLocked(ProcessRecord app) {
2644        int lrui = mLruProcesses.lastIndexOf(app);
2645        if (lrui >= 0) {
2646            if (!app.killed) {
2647                Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2648                Process.killProcessQuiet(app.pid);
2649                Process.killProcessGroup(app.info.uid, app.pid);
2650            }
2651            if (lrui <= mLruProcessActivityStart) {
2652                mLruProcessActivityStart--;
2653            }
2654            if (lrui <= mLruProcessServiceStart) {
2655                mLruProcessServiceStart--;
2656            }
2657            mLruProcesses.remove(lrui);
2658        }
2659    }
2660
2661    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2662            ProcessRecord client) {
2663        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2664                || app.treatLikeActivity;
2665        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2666        if (!activityChange && hasActivity) {
2667            // The process has activities, so we are only allowing activity-based adjustments
2668            // to move it.  It should be kept in the front of the list with other
2669            // processes that have activities, and we don't want those to change their
2670            // order except due to activity operations.
2671            return;
2672        }
2673
2674        mLruSeq++;
2675        final long now = SystemClock.uptimeMillis();
2676        app.lastActivityTime = now;
2677
2678        // First a quick reject: if the app is already at the position we will
2679        // put it, then there is nothing to do.
2680        if (hasActivity) {
2681            final int N = mLruProcesses.size();
2682            if (N > 0 && mLruProcesses.get(N-1) == app) {
2683                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2684                return;
2685            }
2686        } else {
2687            if (mLruProcessServiceStart > 0
2688                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2689                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2690                return;
2691            }
2692        }
2693
2694        int lrui = mLruProcesses.lastIndexOf(app);
2695
2696        if (app.persistent && lrui >= 0) {
2697            // We don't care about the position of persistent processes, as long as
2698            // they are in the list.
2699            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2700            return;
2701        }
2702
2703        /* In progress: compute new position first, so we can avoid doing work
2704           if the process is not actually going to move.  Not yet working.
2705        int addIndex;
2706        int nextIndex;
2707        boolean inActivity = false, inService = false;
2708        if (hasActivity) {
2709            // Process has activities, put it at the very tipsy-top.
2710            addIndex = mLruProcesses.size();
2711            nextIndex = mLruProcessServiceStart;
2712            inActivity = true;
2713        } else if (hasService) {
2714            // Process has services, put it at the top of the service list.
2715            addIndex = mLruProcessActivityStart;
2716            nextIndex = mLruProcessServiceStart;
2717            inActivity = true;
2718            inService = true;
2719        } else  {
2720            // Process not otherwise of interest, it goes to the top of the non-service area.
2721            addIndex = mLruProcessServiceStart;
2722            if (client != null) {
2723                int clientIndex = mLruProcesses.lastIndexOf(client);
2724                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2725                        + app);
2726                if (clientIndex >= 0 && addIndex > clientIndex) {
2727                    addIndex = clientIndex;
2728                }
2729            }
2730            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2731        }
2732
2733        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2734                + mLruProcessActivityStart + "): " + app);
2735        */
2736
2737        if (lrui >= 0) {
2738            if (lrui < mLruProcessActivityStart) {
2739                mLruProcessActivityStart--;
2740            }
2741            if (lrui < mLruProcessServiceStart) {
2742                mLruProcessServiceStart--;
2743            }
2744            /*
2745            if (addIndex > lrui) {
2746                addIndex--;
2747            }
2748            if (nextIndex > lrui) {
2749                nextIndex--;
2750            }
2751            */
2752            mLruProcesses.remove(lrui);
2753        }
2754
2755        /*
2756        mLruProcesses.add(addIndex, app);
2757        if (inActivity) {
2758            mLruProcessActivityStart++;
2759        }
2760        if (inService) {
2761            mLruProcessActivityStart++;
2762        }
2763        */
2764
2765        int nextIndex;
2766        if (hasActivity) {
2767            final int N = mLruProcesses.size();
2768            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2769                // Process doesn't have activities, but has clients with
2770                // activities...  move it up, but one below the top (the top
2771                // should always have a real activity).
2772                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2773                mLruProcesses.add(N-1, app);
2774                // To keep it from spamming the LRU list (by making a bunch of clients),
2775                // we will push down any other entries owned by the app.
2776                final int uid = app.info.uid;
2777                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2778                    ProcessRecord subProc = mLruProcesses.get(i);
2779                    if (subProc.info.uid == uid) {
2780                        // We want to push this one down the list.  If the process after
2781                        // it is for the same uid, however, don't do so, because we don't
2782                        // want them internally to be re-ordered.
2783                        if (mLruProcesses.get(i-1).info.uid != uid) {
2784                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2785                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2786                            ProcessRecord tmp = mLruProcesses.get(i);
2787                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2788                            mLruProcesses.set(i-1, tmp);
2789                            i--;
2790                        }
2791                    } else {
2792                        // A gap, we can stop here.
2793                        break;
2794                    }
2795                }
2796            } else {
2797                // Process has activities, put it at the very tipsy-top.
2798                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2799                mLruProcesses.add(app);
2800            }
2801            nextIndex = mLruProcessServiceStart;
2802        } else if (hasService) {
2803            // Process has services, put it at the top of the service list.
2804            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2805            mLruProcesses.add(mLruProcessActivityStart, app);
2806            nextIndex = mLruProcessServiceStart;
2807            mLruProcessActivityStart++;
2808        } else  {
2809            // Process not otherwise of interest, it goes to the top of the non-service area.
2810            int index = mLruProcessServiceStart;
2811            if (client != null) {
2812                // If there is a client, don't allow the process to be moved up higher
2813                // in the list than that client.
2814                int clientIndex = mLruProcesses.lastIndexOf(client);
2815                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2816                        + " when updating " + app);
2817                if (clientIndex <= lrui) {
2818                    // Don't allow the client index restriction to push it down farther in the
2819                    // list than it already is.
2820                    clientIndex = lrui;
2821                }
2822                if (clientIndex >= 0 && index > clientIndex) {
2823                    index = clientIndex;
2824                }
2825            }
2826            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2827            mLruProcesses.add(index, app);
2828            nextIndex = index-1;
2829            mLruProcessActivityStart++;
2830            mLruProcessServiceStart++;
2831        }
2832
2833        // If the app is currently using a content provider or service,
2834        // bump those processes as well.
2835        for (int j=app.connections.size()-1; j>=0; j--) {
2836            ConnectionRecord cr = app.connections.valueAt(j);
2837            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2838                    && cr.binding.service.app != null
2839                    && cr.binding.service.app.lruSeq != mLruSeq
2840                    && !cr.binding.service.app.persistent) {
2841                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2842                        "service connection", cr, app);
2843            }
2844        }
2845        for (int j=app.conProviders.size()-1; j>=0; j--) {
2846            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2847            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2848                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2849                        "provider reference", cpr, app);
2850            }
2851        }
2852    }
2853
2854    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2855        if (uid == Process.SYSTEM_UID) {
2856            // The system gets to run in any process.  If there are multiple
2857            // processes with the same uid, just pick the first (this
2858            // should never happen).
2859            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2860            if (procs == null) return null;
2861            final int N = procs.size();
2862            for (int i = 0; i < N; i++) {
2863                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2864            }
2865        }
2866        ProcessRecord proc = mProcessNames.get(processName, uid);
2867        if (false && proc != null && !keepIfLarge
2868                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2869                && proc.lastCachedPss >= 4000) {
2870            // Turn this condition on to cause killing to happen regularly, for testing.
2871            if (proc.baseProcessTracker != null) {
2872                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2873            }
2874            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2875        } else if (proc != null && !keepIfLarge
2876                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2877                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2878            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2879            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2880                if (proc.baseProcessTracker != null) {
2881                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2882                }
2883                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2884            }
2885        }
2886        return proc;
2887    }
2888
2889    void ensurePackageDexOpt(String packageName) {
2890        IPackageManager pm = AppGlobals.getPackageManager();
2891        try {
2892            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2893                mDidDexOpt = true;
2894            }
2895        } catch (RemoteException e) {
2896        }
2897    }
2898
2899    boolean isNextTransitionForward() {
2900        int transit = mWindowManager.getPendingAppTransition();
2901        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2902                || transit == AppTransition.TRANSIT_TASK_OPEN
2903                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2904    }
2905
2906    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2907            String processName, String abiOverride, int uid, Runnable crashHandler) {
2908        synchronized(this) {
2909            ApplicationInfo info = new ApplicationInfo();
2910            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2911            // For isolated processes, the former contains the parent's uid and the latter the
2912            // actual uid of the isolated process.
2913            // In the special case introduced by this method (which is, starting an isolated
2914            // process directly from the SystemServer without an actual parent app process) the
2915            // closest thing to a parent's uid is SYSTEM_UID.
2916            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2917            // the |isolated| logic in the ProcessRecord constructor.
2918            info.uid = Process.SYSTEM_UID;
2919            info.processName = processName;
2920            info.className = entryPoint;
2921            info.packageName = "android";
2922            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2923                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2924                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2925                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2926                    crashHandler);
2927            return proc != null ? proc.pid : 0;
2928        }
2929    }
2930
2931    final ProcessRecord startProcessLocked(String processName,
2932            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2933            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2934            boolean isolated, boolean keepIfLarge) {
2935        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2936                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2937                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2938                null /* crashHandler */);
2939    }
2940
2941    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2942            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2943            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2944            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2945        long startTime = SystemClock.elapsedRealtime();
2946        ProcessRecord app;
2947        if (!isolated) {
2948            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2949            checkTime(startTime, "startProcess: after getProcessRecord");
2950        } else {
2951            // If this is an isolated process, it can't re-use an existing process.
2952            app = null;
2953        }
2954        // We don't have to do anything more if:
2955        // (1) There is an existing application record; and
2956        // (2) The caller doesn't think it is dead, OR there is no thread
2957        //     object attached to it so we know it couldn't have crashed; and
2958        // (3) There is a pid assigned to it, so it is either starting or
2959        //     already running.
2960        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2961                + " app=" + app + " knownToBeDead=" + knownToBeDead
2962                + " thread=" + (app != null ? app.thread : null)
2963                + " pid=" + (app != null ? app.pid : -1));
2964        if (app != null && app.pid > 0) {
2965            if (!knownToBeDead || app.thread == null) {
2966                // We already have the app running, or are waiting for it to
2967                // come up (we have a pid but not yet its thread), so keep it.
2968                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2969                // If this is a new package in the process, add the package to the list
2970                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2971                checkTime(startTime, "startProcess: done, added package to proc");
2972                return app;
2973            }
2974
2975            // An application record is attached to a previous process,
2976            // clean it up now.
2977            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2978            checkTime(startTime, "startProcess: bad proc running, killing");
2979            Process.killProcessGroup(app.info.uid, app.pid);
2980            handleAppDiedLocked(app, true, true);
2981            checkTime(startTime, "startProcess: done killing old proc");
2982        }
2983
2984        String hostingNameStr = hostingName != null
2985                ? hostingName.flattenToShortString() : null;
2986
2987        if (!isolated) {
2988            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2989                // If we are in the background, then check to see if this process
2990                // is bad.  If so, we will just silently fail.
2991                if (mBadProcesses.get(info.processName, info.uid) != null) {
2992                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2993                            + "/" + info.processName);
2994                    return null;
2995                }
2996            } else {
2997                // When the user is explicitly starting a process, then clear its
2998                // crash count so that we won't make it bad until they see at
2999                // least one crash dialog again, and make the process good again
3000                // if it had been bad.
3001                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3002                        + "/" + info.processName);
3003                mProcessCrashTimes.remove(info.processName, info.uid);
3004                if (mBadProcesses.get(info.processName, info.uid) != null) {
3005                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3006                            UserHandle.getUserId(info.uid), info.uid,
3007                            info.processName);
3008                    mBadProcesses.remove(info.processName, info.uid);
3009                    if (app != null) {
3010                        app.bad = false;
3011                    }
3012                }
3013            }
3014        }
3015
3016        if (app == null) {
3017            checkTime(startTime, "startProcess: creating new process record");
3018            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3019            app.crashHandler = crashHandler;
3020            if (app == null) {
3021                Slog.w(TAG, "Failed making new process record for "
3022                        + processName + "/" + info.uid + " isolated=" + isolated);
3023                return null;
3024            }
3025            mProcessNames.put(processName, app.uid, app);
3026            if (isolated) {
3027                mIsolatedProcesses.put(app.uid, app);
3028            }
3029            checkTime(startTime, "startProcess: done creating new process record");
3030        } else {
3031            // If this is a new package in the process, add the package to the list
3032            app.addPackage(info.packageName, info.versionCode, mProcessStats);
3033            checkTime(startTime, "startProcess: added package to existing proc");
3034        }
3035
3036        // If the system is not ready yet, then hold off on starting this
3037        // process until it is.
3038        if (!mProcessesReady
3039                && !isAllowedWhileBooting(info)
3040                && !allowWhileBooting) {
3041            if (!mProcessesOnHold.contains(app)) {
3042                mProcessesOnHold.add(app);
3043            }
3044            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3045            checkTime(startTime, "startProcess: returning with proc on hold");
3046            return app;
3047        }
3048
3049        checkTime(startTime, "startProcess: stepping in to startProcess");
3050        startProcessLocked(
3051                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3052        checkTime(startTime, "startProcess: done starting proc!");
3053        return (app.pid != 0) ? app : null;
3054    }
3055
3056    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3057        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3058    }
3059
3060    private final void startProcessLocked(ProcessRecord app,
3061            String hostingType, String hostingNameStr) {
3062        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3063                null /* entryPoint */, null /* entryPointArgs */);
3064    }
3065
3066    private final void startProcessLocked(ProcessRecord app, String hostingType,
3067            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3068        long startTime = SystemClock.elapsedRealtime();
3069        if (app.pid > 0 && app.pid != MY_PID) {
3070            checkTime(startTime, "startProcess: removing from pids map");
3071            synchronized (mPidsSelfLocked) {
3072                mPidsSelfLocked.remove(app.pid);
3073                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3074            }
3075            checkTime(startTime, "startProcess: done removing from pids map");
3076            app.setPid(0);
3077        }
3078
3079        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3080                "startProcessLocked removing on hold: " + app);
3081        mProcessesOnHold.remove(app);
3082
3083        checkTime(startTime, "startProcess: starting to update cpu stats");
3084        updateCpuStats();
3085        checkTime(startTime, "startProcess: done updating cpu stats");
3086
3087        try {
3088            int uid = app.uid;
3089
3090            int[] gids = null;
3091            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3092            if (!app.isolated) {
3093                int[] permGids = null;
3094                try {
3095                    checkTime(startTime, "startProcess: getting gids from package manager");
3096                    final PackageManager pm = mContext.getPackageManager();
3097                    permGids = pm.getPackageGids(app.info.packageName);
3098
3099                    if (Environment.isExternalStorageEmulated()) {
3100                        checkTime(startTime, "startProcess: checking external storage perm");
3101                        if (pm.checkPermission(
3102                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3103                                app.info.packageName) == PERMISSION_GRANTED) {
3104                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3105                        } else {
3106                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3107                        }
3108                    }
3109                } catch (PackageManager.NameNotFoundException e) {
3110                    Slog.w(TAG, "Unable to retrieve gids", e);
3111                }
3112
3113                /*
3114                 * Add shared application and profile GIDs so applications can share some
3115                 * resources like shared libraries and access user-wide resources
3116                 */
3117                if (permGids == null) {
3118                    gids = new int[2];
3119                } else {
3120                    gids = new int[permGids.length + 2];
3121                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3122                }
3123                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3124                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3125            }
3126            checkTime(startTime, "startProcess: building args");
3127            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3128                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3129                        && mTopComponent != null
3130                        && app.processName.equals(mTopComponent.getPackageName())) {
3131                    uid = 0;
3132                }
3133                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3134                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3135                    uid = 0;
3136                }
3137            }
3138            int debugFlags = 0;
3139            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3140                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3141                // Also turn on CheckJNI for debuggable apps. It's quite
3142                // awkward to turn on otherwise.
3143                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3144            }
3145            // Run the app in safe mode if its manifest requests so or the
3146            // system is booted in safe mode.
3147            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3148                mSafeMode == true) {
3149                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3150            }
3151            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3152                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3153            }
3154            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3155                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3156            }
3157            if ("1".equals(SystemProperties.get("debug.assert"))) {
3158                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3159            }
3160
3161            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3162            if (requiredAbi == null) {
3163                requiredAbi = Build.SUPPORTED_ABIS[0];
3164            }
3165
3166            String instructionSet = null;
3167            if (app.info.primaryCpuAbi != null) {
3168                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3169            }
3170
3171            // Start the process.  It will either succeed and return a result containing
3172            // the PID of the new process, or else throw a RuntimeException.
3173            boolean isActivityProcess = (entryPoint == null);
3174            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3175            checkTime(startTime, "startProcess: asking zygote to start proc");
3176            Process.ProcessStartResult startResult = Process.start(entryPoint,
3177                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3178                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3179                    entryPointArgs);
3180            checkTime(startTime, "startProcess: returned from zygote!");
3181
3182            if (app.isolated) {
3183                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3184            }
3185            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3186            checkTime(startTime, "startProcess: done updating battery stats");
3187
3188            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3189                    UserHandle.getUserId(uid), startResult.pid, uid,
3190                    app.processName, hostingType,
3191                    hostingNameStr != null ? hostingNameStr : "");
3192
3193            if (app.persistent) {
3194                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3195            }
3196
3197            checkTime(startTime, "startProcess: building log message");
3198            StringBuilder buf = mStringBuilder;
3199            buf.setLength(0);
3200            buf.append("Start proc ");
3201            buf.append(app.processName);
3202            if (!isActivityProcess) {
3203                buf.append(" [");
3204                buf.append(entryPoint);
3205                buf.append("]");
3206            }
3207            buf.append(" for ");
3208            buf.append(hostingType);
3209            if (hostingNameStr != null) {
3210                buf.append(" ");
3211                buf.append(hostingNameStr);
3212            }
3213            buf.append(": pid=");
3214            buf.append(startResult.pid);
3215            buf.append(" uid=");
3216            buf.append(uid);
3217            buf.append(" gids={");
3218            if (gids != null) {
3219                for (int gi=0; gi<gids.length; gi++) {
3220                    if (gi != 0) buf.append(", ");
3221                    buf.append(gids[gi]);
3222
3223                }
3224            }
3225            buf.append("}");
3226            if (requiredAbi != null) {
3227                buf.append(" abi=");
3228                buf.append(requiredAbi);
3229            }
3230            Slog.i(TAG, buf.toString());
3231            app.setPid(startResult.pid);
3232            app.usingWrapper = startResult.usingWrapper;
3233            app.removed = false;
3234            app.killed = false;
3235            app.killedByAm = false;
3236            checkTime(startTime, "startProcess: starting to update pids map");
3237            synchronized (mPidsSelfLocked) {
3238                this.mPidsSelfLocked.put(startResult.pid, app);
3239                if (isActivityProcess) {
3240                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3241                    msg.obj = app;
3242                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3243                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3244                }
3245            }
3246            checkTime(startTime, "startProcess: done updating pids map");
3247        } catch (RuntimeException e) {
3248            // XXX do better error recovery.
3249            app.setPid(0);
3250            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3251            if (app.isolated) {
3252                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3253            }
3254            Slog.e(TAG, "Failure starting process " + app.processName, e);
3255        }
3256    }
3257
3258    void updateUsageStats(ActivityRecord component, boolean resumed) {
3259        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3260        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3261        if (resumed) {
3262            if (mUsageStatsService != null) {
3263                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3264                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3265            }
3266            synchronized (stats) {
3267                stats.noteActivityResumedLocked(component.app.uid);
3268            }
3269        } else {
3270            if (mUsageStatsService != null) {
3271                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3272                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3273            }
3274            synchronized (stats) {
3275                stats.noteActivityPausedLocked(component.app.uid);
3276            }
3277        }
3278    }
3279
3280    Intent getHomeIntent() {
3281        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3282        intent.setComponent(mTopComponent);
3283        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3284            intent.addCategory(Intent.CATEGORY_HOME);
3285        }
3286        return intent;
3287    }
3288
3289    boolean startHomeActivityLocked(int userId) {
3290        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3291                && mTopAction == null) {
3292            // We are running in factory test mode, but unable to find
3293            // the factory test app, so just sit around displaying the
3294            // error message and don't try to start anything.
3295            return false;
3296        }
3297        Intent intent = getHomeIntent();
3298        ActivityInfo aInfo =
3299            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3300        if (aInfo != null) {
3301            intent.setComponent(new ComponentName(
3302                    aInfo.applicationInfo.packageName, aInfo.name));
3303            // Don't do this if the home app is currently being
3304            // instrumented.
3305            aInfo = new ActivityInfo(aInfo);
3306            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3307            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3308                    aInfo.applicationInfo.uid, true);
3309            if (app == null || app.instrumentationClass == null) {
3310                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3311                mStackSupervisor.startHomeActivity(intent, aInfo);
3312            }
3313        }
3314
3315        return true;
3316    }
3317
3318    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3319        ActivityInfo ai = null;
3320        ComponentName comp = intent.getComponent();
3321        try {
3322            if (comp != null) {
3323                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3324            } else {
3325                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3326                        intent,
3327                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3328                            flags, userId);
3329
3330                if (info != null) {
3331                    ai = info.activityInfo;
3332                }
3333            }
3334        } catch (RemoteException e) {
3335            // ignore
3336        }
3337
3338        return ai;
3339    }
3340
3341    /**
3342     * Starts the "new version setup screen" if appropriate.
3343     */
3344    void startSetupActivityLocked() {
3345        // Only do this once per boot.
3346        if (mCheckedForSetup) {
3347            return;
3348        }
3349
3350        // We will show this screen if the current one is a different
3351        // version than the last one shown, and we are not running in
3352        // low-level factory test mode.
3353        final ContentResolver resolver = mContext.getContentResolver();
3354        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3355                Settings.Global.getInt(resolver,
3356                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3357            mCheckedForSetup = true;
3358
3359            // See if we should be showing the platform update setup UI.
3360            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3361            List<ResolveInfo> ris = mContext.getPackageManager()
3362                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3363
3364            // We don't allow third party apps to replace this.
3365            ResolveInfo ri = null;
3366            for (int i=0; ris != null && i<ris.size(); i++) {
3367                if ((ris.get(i).activityInfo.applicationInfo.flags
3368                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3369                    ri = ris.get(i);
3370                    break;
3371                }
3372            }
3373
3374            if (ri != null) {
3375                String vers = ri.activityInfo.metaData != null
3376                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3377                        : null;
3378                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3379                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3380                            Intent.METADATA_SETUP_VERSION);
3381                }
3382                String lastVers = Settings.Secure.getString(
3383                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3384                if (vers != null && !vers.equals(lastVers)) {
3385                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3386                    intent.setComponent(new ComponentName(
3387                            ri.activityInfo.packageName, ri.activityInfo.name));
3388                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3389                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3390                            null);
3391                }
3392            }
3393        }
3394    }
3395
3396    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3397        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3398    }
3399
3400    void enforceNotIsolatedCaller(String caller) {
3401        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3402            throw new SecurityException("Isolated process not allowed to call " + caller);
3403        }
3404    }
3405
3406    void enforceShellRestriction(String restriction, int userHandle) {
3407        if (Binder.getCallingUid() == Process.SHELL_UID) {
3408            if (userHandle < 0
3409                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
3410                throw new SecurityException("Shell does not have permission to access user "
3411                        + userHandle);
3412            }
3413        }
3414    }
3415
3416    @Override
3417    public int getFrontActivityScreenCompatMode() {
3418        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3419        synchronized (this) {
3420            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3421        }
3422    }
3423
3424    @Override
3425    public void setFrontActivityScreenCompatMode(int mode) {
3426        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3427                "setFrontActivityScreenCompatMode");
3428        synchronized (this) {
3429            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3430        }
3431    }
3432
3433    @Override
3434    public int getPackageScreenCompatMode(String packageName) {
3435        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3436        synchronized (this) {
3437            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3438        }
3439    }
3440
3441    @Override
3442    public void setPackageScreenCompatMode(String packageName, int mode) {
3443        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3444                "setPackageScreenCompatMode");
3445        synchronized (this) {
3446            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3447        }
3448    }
3449
3450    @Override
3451    public boolean getPackageAskScreenCompat(String packageName) {
3452        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3453        synchronized (this) {
3454            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3455        }
3456    }
3457
3458    @Override
3459    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3460        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3461                "setPackageAskScreenCompat");
3462        synchronized (this) {
3463            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3464        }
3465    }
3466
3467    private void dispatchProcessesChanged() {
3468        int N;
3469        synchronized (this) {
3470            N = mPendingProcessChanges.size();
3471            if (mActiveProcessChanges.length < N) {
3472                mActiveProcessChanges = new ProcessChangeItem[N];
3473            }
3474            mPendingProcessChanges.toArray(mActiveProcessChanges);
3475            mAvailProcessChanges.addAll(mPendingProcessChanges);
3476            mPendingProcessChanges.clear();
3477            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3478        }
3479
3480        int i = mProcessObservers.beginBroadcast();
3481        while (i > 0) {
3482            i--;
3483            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3484            if (observer != null) {
3485                try {
3486                    for (int j=0; j<N; j++) {
3487                        ProcessChangeItem item = mActiveProcessChanges[j];
3488                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3489                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3490                                    + item.pid + " uid=" + item.uid + ": "
3491                                    + item.foregroundActivities);
3492                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3493                                    item.foregroundActivities);
3494                        }
3495                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3496                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3497                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3498                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3499                        }
3500                    }
3501                } catch (RemoteException e) {
3502                }
3503            }
3504        }
3505        mProcessObservers.finishBroadcast();
3506    }
3507
3508    private void dispatchProcessDied(int pid, int uid) {
3509        int i = mProcessObservers.beginBroadcast();
3510        while (i > 0) {
3511            i--;
3512            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3513            if (observer != null) {
3514                try {
3515                    observer.onProcessDied(pid, uid);
3516                } catch (RemoteException e) {
3517                }
3518            }
3519        }
3520        mProcessObservers.finishBroadcast();
3521    }
3522
3523    @Override
3524    public final int startActivity(IApplicationThread caller, String callingPackage,
3525            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3526            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3527        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3528            resultWho, requestCode, startFlags, profilerInfo, options,
3529            UserHandle.getCallingUserId());
3530    }
3531
3532    @Override
3533    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3534            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3535            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3536        enforceNotIsolatedCaller("startActivity");
3537        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3538                false, ALLOW_FULL_ONLY, "startActivity", null);
3539        // TODO: Switch to user app stacks here.
3540        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3541                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3542                profilerInfo, null, null, options, userId, null, null);
3543    }
3544
3545    @Override
3546    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3547            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3548            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3549
3550        // This is very dangerous -- it allows you to perform a start activity (including
3551        // permission grants) as any app that may launch one of your own activities.  So
3552        // we will only allow this to be done from activities that are part of the core framework,
3553        // and then only when they are running as the system.
3554        final ActivityRecord sourceRecord;
3555        final int targetUid;
3556        final String targetPackage;
3557        synchronized (this) {
3558            if (resultTo == null) {
3559                throw new SecurityException("Must be called from an activity");
3560            }
3561            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3562            if (sourceRecord == null) {
3563                throw new SecurityException("Called with bad activity token: " + resultTo);
3564            }
3565            if (!sourceRecord.info.packageName.equals("android")) {
3566                throw new SecurityException(
3567                        "Must be called from an activity that is declared in the android package");
3568            }
3569            if (sourceRecord.app == null) {
3570                throw new SecurityException("Called without a process attached to activity");
3571            }
3572            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3573                // This is still okay, as long as this activity is running under the
3574                // uid of the original calling activity.
3575                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3576                    throw new SecurityException(
3577                            "Calling activity in uid " + sourceRecord.app.uid
3578                                    + " must be system uid or original calling uid "
3579                                    + sourceRecord.launchedFromUid);
3580                }
3581            }
3582            targetUid = sourceRecord.launchedFromUid;
3583            targetPackage = sourceRecord.launchedFromPackage;
3584        }
3585
3586        // TODO: Switch to user app stacks here.
3587        try {
3588            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3589                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3590                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3591            return ret;
3592        } catch (SecurityException e) {
3593            // XXX need to figure out how to propagate to original app.
3594            // A SecurityException here is generally actually a fault of the original
3595            // calling activity (such as a fairly granting permissions), so propagate it
3596            // back to them.
3597            /*
3598            StringBuilder msg = new StringBuilder();
3599            msg.append("While launching");
3600            msg.append(intent.toString());
3601            msg.append(": ");
3602            msg.append(e.getMessage());
3603            */
3604            throw e;
3605        }
3606    }
3607
3608    @Override
3609    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3610            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3611            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3612        enforceNotIsolatedCaller("startActivityAndWait");
3613        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3614                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3615        WaitResult res = new WaitResult();
3616        // TODO: Switch to user app stacks here.
3617        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3618                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3619                options, userId, null, null);
3620        return res;
3621    }
3622
3623    @Override
3624    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3625            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3626            int startFlags, Configuration config, Bundle options, int userId) {
3627        enforceNotIsolatedCaller("startActivityWithConfig");
3628        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3629                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3630        // TODO: Switch to user app stacks here.
3631        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3632                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3633                null, null, config, options, userId, null, null);
3634        return ret;
3635    }
3636
3637    @Override
3638    public int startActivityIntentSender(IApplicationThread caller,
3639            IntentSender intent, Intent fillInIntent, String resolvedType,
3640            IBinder resultTo, String resultWho, int requestCode,
3641            int flagsMask, int flagsValues, Bundle options) {
3642        enforceNotIsolatedCaller("startActivityIntentSender");
3643        // Refuse possible leaked file descriptors
3644        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3645            throw new IllegalArgumentException("File descriptors passed in Intent");
3646        }
3647
3648        IIntentSender sender = intent.getTarget();
3649        if (!(sender instanceof PendingIntentRecord)) {
3650            throw new IllegalArgumentException("Bad PendingIntent object");
3651        }
3652
3653        PendingIntentRecord pir = (PendingIntentRecord)sender;
3654
3655        synchronized (this) {
3656            // If this is coming from the currently resumed activity, it is
3657            // effectively saying that app switches are allowed at this point.
3658            final ActivityStack stack = getFocusedStack();
3659            if (stack.mResumedActivity != null &&
3660                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3661                mAppSwitchesAllowedTime = 0;
3662            }
3663        }
3664        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3665                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3666        return ret;
3667    }
3668
3669    @Override
3670    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3671            Intent intent, String resolvedType, IVoiceInteractionSession session,
3672            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3673            Bundle options, int userId) {
3674        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3675                != PackageManager.PERMISSION_GRANTED) {
3676            String msg = "Permission Denial: startVoiceActivity() from pid="
3677                    + Binder.getCallingPid()
3678                    + ", uid=" + Binder.getCallingUid()
3679                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3680            Slog.w(TAG, msg);
3681            throw new SecurityException(msg);
3682        }
3683        if (session == null || interactor == null) {
3684            throw new NullPointerException("null session or interactor");
3685        }
3686        userId = handleIncomingUser(callingPid, callingUid, userId,
3687                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3688        // TODO: Switch to user app stacks here.
3689        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3690                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3691                null, options, userId, null, null);
3692    }
3693
3694    @Override
3695    public boolean startNextMatchingActivity(IBinder callingActivity,
3696            Intent intent, Bundle options) {
3697        // Refuse possible leaked file descriptors
3698        if (intent != null && intent.hasFileDescriptors() == true) {
3699            throw new IllegalArgumentException("File descriptors passed in Intent");
3700        }
3701
3702        synchronized (this) {
3703            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3704            if (r == null) {
3705                ActivityOptions.abort(options);
3706                return false;
3707            }
3708            if (r.app == null || r.app.thread == null) {
3709                // The caller is not running...  d'oh!
3710                ActivityOptions.abort(options);
3711                return false;
3712            }
3713            intent = new Intent(intent);
3714            // The caller is not allowed to change the data.
3715            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3716            // And we are resetting to find the next component...
3717            intent.setComponent(null);
3718
3719            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3720
3721            ActivityInfo aInfo = null;
3722            try {
3723                List<ResolveInfo> resolves =
3724                    AppGlobals.getPackageManager().queryIntentActivities(
3725                            intent, r.resolvedType,
3726                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3727                            UserHandle.getCallingUserId());
3728
3729                // Look for the original activity in the list...
3730                final int N = resolves != null ? resolves.size() : 0;
3731                for (int i=0; i<N; i++) {
3732                    ResolveInfo rInfo = resolves.get(i);
3733                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3734                            && rInfo.activityInfo.name.equals(r.info.name)) {
3735                        // We found the current one...  the next matching is
3736                        // after it.
3737                        i++;
3738                        if (i<N) {
3739                            aInfo = resolves.get(i).activityInfo;
3740                        }
3741                        if (debug) {
3742                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3743                                    + "/" + r.info.name);
3744                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3745                                    + "/" + aInfo.name);
3746                        }
3747                        break;
3748                    }
3749                }
3750            } catch (RemoteException e) {
3751            }
3752
3753            if (aInfo == null) {
3754                // Nobody who is next!
3755                ActivityOptions.abort(options);
3756                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3757                return false;
3758            }
3759
3760            intent.setComponent(new ComponentName(
3761                    aInfo.applicationInfo.packageName, aInfo.name));
3762            intent.setFlags(intent.getFlags()&~(
3763                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3764                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3765                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3766                    Intent.FLAG_ACTIVITY_NEW_TASK));
3767
3768            // Okay now we need to start the new activity, replacing the
3769            // currently running activity.  This is a little tricky because
3770            // we want to start the new one as if the current one is finished,
3771            // but not finish the current one first so that there is no flicker.
3772            // And thus...
3773            final boolean wasFinishing = r.finishing;
3774            r.finishing = true;
3775
3776            // Propagate reply information over to the new activity.
3777            final ActivityRecord resultTo = r.resultTo;
3778            final String resultWho = r.resultWho;
3779            final int requestCode = r.requestCode;
3780            r.resultTo = null;
3781            if (resultTo != null) {
3782                resultTo.removeResultsLocked(r, resultWho, requestCode);
3783            }
3784
3785            final long origId = Binder.clearCallingIdentity();
3786            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3787                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3788                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3789                    -1, r.launchedFromUid, 0, options, false, null, null, null);
3790            Binder.restoreCallingIdentity(origId);
3791
3792            r.finishing = wasFinishing;
3793            if (res != ActivityManager.START_SUCCESS) {
3794                return false;
3795            }
3796            return true;
3797        }
3798    }
3799
3800    @Override
3801    public final int startActivityFromRecents(int taskId, Bundle options) {
3802        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: startActivityFromRecents called without " +
3804                    START_TASKS_FROM_RECENTS;
3805            Slog.w(TAG, msg);
3806            throw new SecurityException(msg);
3807        }
3808        return startActivityFromRecentsInner(taskId, options);
3809    }
3810
3811    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3812        final TaskRecord task;
3813        final int callingUid;
3814        final String callingPackage;
3815        final Intent intent;
3816        final int userId;
3817        synchronized (this) {
3818            task = recentTaskForIdLocked(taskId);
3819            if (task == null) {
3820                throw new IllegalArgumentException("Task " + taskId + " not found.");
3821            }
3822            callingUid = task.mCallingUid;
3823            callingPackage = task.mCallingPackage;
3824            intent = task.intent;
3825            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3826            userId = task.userId;
3827        }
3828        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3829                options, userId, null, task);
3830    }
3831
3832    final int startActivityInPackage(int uid, String callingPackage,
3833            Intent intent, String resolvedType, IBinder resultTo,
3834            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3835            IActivityContainer container, TaskRecord inTask) {
3836
3837        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3838                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3839
3840        // TODO: Switch to user app stacks here.
3841        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3842                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3843                null, null, null, options, userId, container, inTask);
3844        return ret;
3845    }
3846
3847    @Override
3848    public final int startActivities(IApplicationThread caller, String callingPackage,
3849            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3850            int userId) {
3851        enforceNotIsolatedCaller("startActivities");
3852        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3853                false, ALLOW_FULL_ONLY, "startActivity", null);
3854        // TODO: Switch to user app stacks here.
3855        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3856                resolvedTypes, resultTo, options, userId);
3857        return ret;
3858    }
3859
3860    final int startActivitiesInPackage(int uid, String callingPackage,
3861            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3862            Bundle options, int userId) {
3863
3864        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3865                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3866        // TODO: Switch to user app stacks here.
3867        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3868                resultTo, options, userId);
3869        return ret;
3870    }
3871
3872    //explicitly remove thd old information in mRecentTasks when removing existing user.
3873    private void removeRecentTasksForUserLocked(int userId) {
3874        if(userId <= 0) {
3875            Slog.i(TAG, "Can't remove recent task on user " + userId);
3876            return;
3877        }
3878
3879        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3880            TaskRecord tr = mRecentTasks.get(i);
3881            if (tr.userId == userId) {
3882                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3883                        + " when finishing user" + userId);
3884                mRecentTasks.remove(i);
3885                tr.removedFromRecents(mTaskPersister);
3886            }
3887        }
3888
3889        // Remove tasks from persistent storage.
3890        mTaskPersister.wakeup(null, true);
3891    }
3892
3893    // Sort by taskId
3894    private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3895        @Override
3896        public int compare(TaskRecord lhs, TaskRecord rhs) {
3897            return rhs.taskId - lhs.taskId;
3898        }
3899    };
3900
3901    // Extract the affiliates of the chain containing mRecentTasks[start].
3902    private int processNextAffiliateChain(int start) {
3903        final TaskRecord startTask = mRecentTasks.get(start);
3904        final int affiliateId = startTask.mAffiliatedTaskId;
3905
3906        // Quick identification of isolated tasks. I.e. those not launched behind.
3907        if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3908                startTask.mNextAffiliate == null) {
3909            // There is still a slim chance that there are other tasks that point to this task
3910            // and that the chain is so messed up that this task no longer points to them but
3911            // the gain of this optimization outweighs the risk.
3912            startTask.inRecents = true;
3913            return start + 1;
3914        }
3915
3916        // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3917        mTmpRecents.clear();
3918        for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3919            final TaskRecord task = mRecentTasks.get(i);
3920            if (task.mAffiliatedTaskId == affiliateId) {
3921                mRecentTasks.remove(i);
3922                mTmpRecents.add(task);
3923            }
3924        }
3925
3926        // Sort them all by taskId. That is the order they were create in and that order will
3927        // always be correct.
3928        Collections.sort(mTmpRecents, mTaskRecordComparator);
3929
3930        // Go through and fix up the linked list.
3931        // The first one is the end of the chain and has no next.
3932        final TaskRecord first = mTmpRecents.get(0);
3933        first.inRecents = true;
3934        if (first.mNextAffiliate != null) {
3935            Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3936            first.setNextAffiliate(null);
3937            mTaskPersister.wakeup(first, false);
3938        }
3939        // Everything in the middle is doubly linked from next to prev.
3940        final int tmpSize = mTmpRecents.size();
3941        for (int i = 0; i < tmpSize - 1; ++i) {
3942            final TaskRecord next = mTmpRecents.get(i);
3943            final TaskRecord prev = mTmpRecents.get(i + 1);
3944            if (next.mPrevAffiliate != prev) {
3945                Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3946                        " setting prev=" + prev);
3947                next.setPrevAffiliate(prev);
3948                mTaskPersister.wakeup(next, false);
3949            }
3950            if (prev.mNextAffiliate != next) {
3951                Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3952                        " setting next=" + next);
3953                prev.setNextAffiliate(next);
3954                mTaskPersister.wakeup(prev, false);
3955            }
3956            prev.inRecents = true;
3957        }
3958        // The last one is the beginning of the list and has no prev.
3959        final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3960        if (last.mPrevAffiliate != null) {
3961            Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3962            last.setPrevAffiliate(null);
3963            mTaskPersister.wakeup(last, false);
3964        }
3965
3966        // Insert the group back into mRecentTasks at start.
3967        mRecentTasks.addAll(start, mTmpRecents);
3968
3969        // Let the caller know where we left off.
3970        return start + tmpSize;
3971    }
3972
3973    /**
3974     * Update the recent tasks lists: make sure tasks should still be here (their
3975     * applications / activities still exist), update their availability, fixup ordering
3976     * of affiliations.
3977     */
3978    void cleanupRecentTasksLocked(int userId) {
3979        if (mRecentTasks == null) {
3980            // Happens when called from the packagemanager broadcast before boot.
3981            return;
3982        }
3983
3984        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3985        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3986        final IPackageManager pm = AppGlobals.getPackageManager();
3987        final ActivityInfo dummyAct = new ActivityInfo();
3988        final ApplicationInfo dummyApp = new ApplicationInfo();
3989
3990        int N = mRecentTasks.size();
3991
3992        int[] users = userId == UserHandle.USER_ALL
3993                ? getUsersLocked() : new int[] { userId };
3994        for (int user : users) {
3995            for (int i = 0; i < N; i++) {
3996                TaskRecord task = mRecentTasks.get(i);
3997                if (task.userId != user) {
3998                    // Only look at tasks for the user ID of interest.
3999                    continue;
4000                }
4001                if (task.autoRemoveRecents && task.getTopActivity() == null) {
4002                    // This situation is broken, and we should just get rid of it now.
4003                    mRecentTasks.remove(i);
4004                    task.removedFromRecents(mTaskPersister);
4005                    i--;
4006                    N--;
4007                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
4008                    continue;
4009                }
4010                // Check whether this activity is currently available.
4011                if (task.realActivity != null) {
4012                    ActivityInfo ai = availActCache.get(task.realActivity);
4013                    if (ai == null) {
4014                        try {
4015                            ai = pm.getActivityInfo(task.realActivity,
4016                                    PackageManager.GET_UNINSTALLED_PACKAGES
4017                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
4018                        } catch (RemoteException e) {
4019                            // Will never happen.
4020                            continue;
4021                        }
4022                        if (ai == null) {
4023                            ai = dummyAct;
4024                        }
4025                        availActCache.put(task.realActivity, ai);
4026                    }
4027                    if (ai == dummyAct) {
4028                        // This could be either because the activity no longer exists, or the
4029                        // app is temporarily gone.  For the former we want to remove the recents
4030                        // entry; for the latter we want to mark it as unavailable.
4031                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4032                        if (app == null) {
4033                            try {
4034                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4035                                        PackageManager.GET_UNINSTALLED_PACKAGES
4036                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
4037                            } catch (RemoteException e) {
4038                                // Will never happen.
4039                                continue;
4040                            }
4041                            if (app == null) {
4042                                app = dummyApp;
4043                            }
4044                            availAppCache.put(task.realActivity.getPackageName(), app);
4045                        }
4046                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4047                            // Doesn't exist any more!  Good-bye.
4048                            mRecentTasks.remove(i);
4049                            task.removedFromRecents(mTaskPersister);
4050                            i--;
4051                            N--;
4052                            Slog.w(TAG, "Removing no longer valid recent: " + task);
4053                            continue;
4054                        } else {
4055                            // Otherwise just not available for now.
4056                            if (task.isAvailable) {
4057                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4058                                        + task);
4059                            }
4060                            task.isAvailable = false;
4061                        }
4062                    } else {
4063                        if (!ai.enabled || !ai.applicationInfo.enabled
4064                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4065                            if (task.isAvailable) {
4066                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4067                                        + task + " (enabled=" + ai.enabled + "/"
4068                                        + ai.applicationInfo.enabled +  " flags="
4069                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
4070                            }
4071                            task.isAvailable = false;
4072                        } else {
4073                            if (!task.isAvailable) {
4074                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4075                                        + task);
4076                            }
4077                            task.isAvailable = true;
4078                        }
4079                    }
4080                }
4081            }
4082        }
4083
4084        // Verify the affiliate chain for each task.
4085        for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4086        }
4087
4088        mTmpRecents.clear();
4089        // mRecentTasks is now in sorted, affiliated order.
4090    }
4091
4092    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4093        int N = mRecentTasks.size();
4094        TaskRecord top = task;
4095        int topIndex = taskIndex;
4096        while (top.mNextAffiliate != null && topIndex > 0) {
4097            top = top.mNextAffiliate;
4098            topIndex--;
4099        }
4100        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4101                + topIndex + " from intial " + taskIndex);
4102        // Find the end of the chain, doing a sanity check along the way.
4103        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4104        int endIndex = topIndex;
4105        TaskRecord prev = top;
4106        while (endIndex < N) {
4107            TaskRecord cur = mRecentTasks.get(endIndex);
4108            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4109                    + endIndex + " " + cur);
4110            if (cur == top) {
4111                // Verify start of the chain.
4112                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4113                    Slog.wtf(TAG, "Bad chain @" + endIndex
4114                            + ": first task has next affiliate: " + prev);
4115                    sane = false;
4116                    break;
4117                }
4118            } else {
4119                // Verify middle of the chain's next points back to the one before.
4120                if (cur.mNextAffiliate != prev
4121                        || cur.mNextAffiliateTaskId != prev.taskId) {
4122                    Slog.wtf(TAG, "Bad chain @" + endIndex
4123                            + ": middle task " + cur + " @" + endIndex
4124                            + " has bad next affiliate "
4125                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4126                            + ", expected " + prev);
4127                    sane = false;
4128                    break;
4129                }
4130            }
4131            if (cur.mPrevAffiliateTaskId == -1) {
4132                // Chain ends here.
4133                if (cur.mPrevAffiliate != null) {
4134                    Slog.wtf(TAG, "Bad chain @" + endIndex
4135                            + ": last task " + cur + " has previous affiliate "
4136                            + cur.mPrevAffiliate);
4137                    sane = false;
4138                }
4139                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4140                break;
4141            } else {
4142                // Verify middle of the chain's prev points to a valid item.
4143                if (cur.mPrevAffiliate == null) {
4144                    Slog.wtf(TAG, "Bad chain @" + endIndex
4145                            + ": task " + cur + " has previous affiliate "
4146                            + cur.mPrevAffiliate + " but should be id "
4147                            + cur.mPrevAffiliate);
4148                    sane = false;
4149                    break;
4150                }
4151            }
4152            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4153                Slog.wtf(TAG, "Bad chain @" + endIndex
4154                        + ": task " + cur + " has affiliated id "
4155                        + cur.mAffiliatedTaskId + " but should be "
4156                        + task.mAffiliatedTaskId);
4157                sane = false;
4158                break;
4159            }
4160            prev = cur;
4161            endIndex++;
4162            if (endIndex >= N) {
4163                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4164                        + ": last task " + prev);
4165                sane = false;
4166                break;
4167            }
4168        }
4169        if (sane) {
4170            if (endIndex < taskIndex) {
4171                Slog.wtf(TAG, "Bad chain @" + endIndex
4172                        + ": did not extend to task " + task + " @" + taskIndex);
4173                sane = false;
4174            }
4175        }
4176        if (sane) {
4177            // All looks good, we can just move all of the affiliated tasks
4178            // to the top.
4179            for (int i=topIndex; i<=endIndex; i++) {
4180                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4181                        + " from " + i + " to " + (i-topIndex));
4182                TaskRecord cur = mRecentTasks.remove(i);
4183                mRecentTasks.add(i-topIndex, cur);
4184            }
4185            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4186                    + " to " + endIndex);
4187            return true;
4188        }
4189
4190        // Whoops, couldn't do it.
4191        return false;
4192    }
4193
4194    final void addRecentTaskLocked(TaskRecord task) {
4195        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4196                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4197
4198        int N = mRecentTasks.size();
4199        // Quick case: check if the top-most recent task is the same.
4200        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4201            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4202            return;
4203        }
4204        // Another quick case: check if this is part of a set of affiliated
4205        // tasks that are at the top.
4206        if (isAffiliated && N > 0 && task.inRecents
4207                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4208            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4209                    + " at top when adding " + task);
4210            return;
4211        }
4212        // Another quick case: never add voice sessions.
4213        if (task.voiceSession != null) {
4214            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4215            return;
4216        }
4217
4218        boolean needAffiliationFix = false;
4219
4220        // Slightly less quick case: the task is already in recents, so all we need
4221        // to do is move it.
4222        if (task.inRecents) {
4223            int taskIndex = mRecentTasks.indexOf(task);
4224            if (taskIndex >= 0) {
4225                if (!isAffiliated) {
4226                    // Simple case: this is not an affiliated task, so we just move it to the front.
4227                    mRecentTasks.remove(taskIndex);
4228                    mRecentTasks.add(0, task);
4229                    notifyTaskPersisterLocked(task, false);
4230                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4231                            + " from " + taskIndex);
4232                    return;
4233                } else {
4234                    // More complicated: need to keep all affiliated tasks together.
4235                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4236                        // All went well.
4237                        return;
4238                    }
4239
4240                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4241                    // everything and then go through our general path of adding a new task.
4242                    needAffiliationFix = true;
4243                }
4244            } else {
4245                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4246                needAffiliationFix = true;
4247            }
4248        }
4249
4250        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4251        trimRecentsForTask(task, true);
4252
4253        N = mRecentTasks.size();
4254        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4255            final TaskRecord tr = mRecentTasks.remove(N - 1);
4256            tr.removedFromRecents(mTaskPersister);
4257            N--;
4258        }
4259        task.inRecents = true;
4260        if (!isAffiliated || needAffiliationFix) {
4261            // If this is a simple non-affiliated task, or we had some failure trying to
4262            // handle it as part of an affilated task, then just place it at the top.
4263            mRecentTasks.add(0, task);
4264        } else if (isAffiliated) {
4265            // If this is a new affiliated task, then move all of the affiliated tasks
4266            // to the front and insert this new one.
4267            TaskRecord other = task.mNextAffiliate;
4268            if (other == null) {
4269                other = task.mPrevAffiliate;
4270            }
4271            if (other != null) {
4272                int otherIndex = mRecentTasks.indexOf(other);
4273                if (otherIndex >= 0) {
4274                    // Insert new task at appropriate location.
4275                    int taskIndex;
4276                    if (other == task.mNextAffiliate) {
4277                        // We found the index of our next affiliation, which is who is
4278                        // before us in the list, so add after that point.
4279                        taskIndex = otherIndex+1;
4280                    } else {
4281                        // We found the index of our previous affiliation, which is who is
4282                        // after us in the list, so add at their position.
4283                        taskIndex = otherIndex;
4284                    }
4285                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4286                            + taskIndex + ": " + task);
4287                    mRecentTasks.add(taskIndex, task);
4288
4289                    // Now move everything to the front.
4290                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4291                        // All went well.
4292                        return;
4293                    }
4294
4295                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4296                    // everything and then go through our general path of adding a new task.
4297                    needAffiliationFix = true;
4298                } else {
4299                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4300                            + other);
4301                    needAffiliationFix = true;
4302                }
4303            } else {
4304                if (DEBUG_RECENTS) Slog.d(TAG,
4305                        "addRecent: adding affiliated task without next/prev:" + task);
4306                needAffiliationFix = true;
4307            }
4308        }
4309        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4310
4311        if (needAffiliationFix) {
4312            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4313            cleanupRecentTasksLocked(task.userId);
4314        }
4315    }
4316
4317    /**
4318     * If needed, remove oldest existing entries in recents that are for the same kind
4319     * of task as the given one.
4320     */
4321    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4322        int N = mRecentTasks.size();
4323        final Intent intent = task.intent;
4324        final boolean document = intent != null && intent.isDocument();
4325
4326        int maxRecents = task.maxRecents - 1;
4327        for (int i=0; i<N; i++) {
4328            final TaskRecord tr = mRecentTasks.get(i);
4329            if (task != tr) {
4330                if (task.userId != tr.userId) {
4331                    continue;
4332                }
4333                if (i > MAX_RECENT_BITMAPS) {
4334                    tr.freeLastThumbnail();
4335                }
4336                final Intent trIntent = tr.intent;
4337                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4338                    (intent == null || !intent.filterEquals(trIntent))) {
4339                    continue;
4340                }
4341                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4342                if (document && trIsDocument) {
4343                    // These are the same document activity (not necessarily the same doc).
4344                    if (maxRecents > 0) {
4345                        --maxRecents;
4346                        continue;
4347                    }
4348                    // Hit the maximum number of documents for this task. Fall through
4349                    // and remove this document from recents.
4350                } else if (document || trIsDocument) {
4351                    // Only one of these is a document. Not the droid we're looking for.
4352                    continue;
4353                }
4354            }
4355
4356            if (!doTrim) {
4357                // If the caller is not actually asking for a trim, just tell them we reached
4358                // a point where the trim would happen.
4359                return i;
4360            }
4361
4362            // Either task and tr are the same or, their affinities match or their intents match
4363            // and neither of them is a document, or they are documents using the same activity
4364            // and their maxRecents has been reached.
4365            tr.disposeThumbnail();
4366            mRecentTasks.remove(i);
4367            if (task != tr) {
4368                tr.removedFromRecents(mTaskPersister);
4369            }
4370            i--;
4371            N--;
4372            if (task.intent == null) {
4373                // If the new recent task we are adding is not fully
4374                // specified, then replace it with the existing recent task.
4375                task = tr;
4376            }
4377            notifyTaskPersisterLocked(tr, false);
4378        }
4379
4380        return -1;
4381    }
4382
4383    @Override
4384    public void reportActivityFullyDrawn(IBinder token) {
4385        synchronized (this) {
4386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4387            if (r == null) {
4388                return;
4389            }
4390            r.reportFullyDrawnLocked();
4391        }
4392    }
4393
4394    @Override
4395    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4396        synchronized (this) {
4397            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4398            if (r == null) {
4399                return;
4400            }
4401            final long origId = Binder.clearCallingIdentity();
4402            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4403            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4404                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4405            if (config != null) {
4406                r.frozenBeforeDestroy = true;
4407                if (!updateConfigurationLocked(config, r, false, false)) {
4408                    mStackSupervisor.resumeTopActivitiesLocked();
4409                }
4410            }
4411            Binder.restoreCallingIdentity(origId);
4412        }
4413    }
4414
4415    @Override
4416    public int getRequestedOrientation(IBinder token) {
4417        synchronized (this) {
4418            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4419            if (r == null) {
4420                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4421            }
4422            return mWindowManager.getAppOrientation(r.appToken);
4423        }
4424    }
4425
4426    /**
4427     * This is the internal entry point for handling Activity.finish().
4428     *
4429     * @param token The Binder token referencing the Activity we want to finish.
4430     * @param resultCode Result code, if any, from this Activity.
4431     * @param resultData Result data (Intent), if any, from this Activity.
4432     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4433     *            the root Activity in the task.
4434     *
4435     * @return Returns true if the activity successfully finished, or false if it is still running.
4436     */
4437    @Override
4438    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4439            boolean finishTask) {
4440        // Refuse possible leaked file descriptors
4441        if (resultData != null && resultData.hasFileDescriptors() == true) {
4442            throw new IllegalArgumentException("File descriptors passed in Intent");
4443        }
4444
4445        synchronized(this) {
4446            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4447            if (r == null) {
4448                return true;
4449            }
4450            // Keep track of the root activity of the task before we finish it
4451            TaskRecord tr = r.task;
4452            ActivityRecord rootR = tr.getRootActivity();
4453            // Do not allow task to finish in Lock Task mode.
4454            if (tr == mStackSupervisor.mLockTaskModeTask) {
4455                if (rootR == r) {
4456                    mStackSupervisor.showLockTaskToast();
4457                    return false;
4458                }
4459            }
4460            if (mController != null) {
4461                // Find the first activity that is not finishing.
4462                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4463                if (next != null) {
4464                    // ask watcher if this is allowed
4465                    boolean resumeOK = true;
4466                    try {
4467                        resumeOK = mController.activityResuming(next.packageName);
4468                    } catch (RemoteException e) {
4469                        mController = null;
4470                        Watchdog.getInstance().setActivityController(null);
4471                    }
4472
4473                    if (!resumeOK) {
4474                        return false;
4475                    }
4476                }
4477            }
4478            final long origId = Binder.clearCallingIdentity();
4479            try {
4480                boolean res;
4481                if (finishTask && r == rootR) {
4482                    // If requested, remove the task that is associated to this activity only if it
4483                    // was the root activity in the task.  The result code and data is ignored because
4484                    // we don't support returning them across task boundaries.
4485                    res = removeTaskByIdLocked(tr.taskId, 0);
4486                } else {
4487                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4488                            resultData, "app-request", true);
4489                }
4490                return res;
4491            } finally {
4492                Binder.restoreCallingIdentity(origId);
4493            }
4494        }
4495    }
4496
4497    @Override
4498    public final void finishHeavyWeightApp() {
4499        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4500                != PackageManager.PERMISSION_GRANTED) {
4501            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4502                    + Binder.getCallingPid()
4503                    + ", uid=" + Binder.getCallingUid()
4504                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4505            Slog.w(TAG, msg);
4506            throw new SecurityException(msg);
4507        }
4508
4509        synchronized(this) {
4510            if (mHeavyWeightProcess == null) {
4511                return;
4512            }
4513
4514            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4515                    mHeavyWeightProcess.activities);
4516            for (int i=0; i<activities.size(); i++) {
4517                ActivityRecord r = activities.get(i);
4518                if (!r.finishing) {
4519                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4520                            null, "finish-heavy", true);
4521                }
4522            }
4523
4524            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4525                    mHeavyWeightProcess.userId, 0));
4526            mHeavyWeightProcess = null;
4527        }
4528    }
4529
4530    @Override
4531    public void crashApplication(int uid, int initialPid, String packageName,
4532            String message) {
4533        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4534                != PackageManager.PERMISSION_GRANTED) {
4535            String msg = "Permission Denial: crashApplication() from pid="
4536                    + Binder.getCallingPid()
4537                    + ", uid=" + Binder.getCallingUid()
4538                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4539            Slog.w(TAG, msg);
4540            throw new SecurityException(msg);
4541        }
4542
4543        synchronized(this) {
4544            ProcessRecord proc = null;
4545
4546            // Figure out which process to kill.  We don't trust that initialPid
4547            // still has any relation to current pids, so must scan through the
4548            // list.
4549            synchronized (mPidsSelfLocked) {
4550                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4551                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4552                    if (p.uid != uid) {
4553                        continue;
4554                    }
4555                    if (p.pid == initialPid) {
4556                        proc = p;
4557                        break;
4558                    }
4559                    if (p.pkgList.containsKey(packageName)) {
4560                        proc = p;
4561                    }
4562                }
4563            }
4564
4565            if (proc == null) {
4566                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4567                        + " initialPid=" + initialPid
4568                        + " packageName=" + packageName);
4569                return;
4570            }
4571
4572            if (proc.thread != null) {
4573                if (proc.pid == Process.myPid()) {
4574                    Log.w(TAG, "crashApplication: trying to crash self!");
4575                    return;
4576                }
4577                long ident = Binder.clearCallingIdentity();
4578                try {
4579                    proc.thread.scheduleCrash(message);
4580                } catch (RemoteException e) {
4581                }
4582                Binder.restoreCallingIdentity(ident);
4583            }
4584        }
4585    }
4586
4587    @Override
4588    public final void finishSubActivity(IBinder token, String resultWho,
4589            int requestCode) {
4590        synchronized(this) {
4591            final long origId = Binder.clearCallingIdentity();
4592            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4593            if (r != null) {
4594                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4595            }
4596            Binder.restoreCallingIdentity(origId);
4597        }
4598    }
4599
4600    @Override
4601    public boolean finishActivityAffinity(IBinder token) {
4602        synchronized(this) {
4603            final long origId = Binder.clearCallingIdentity();
4604            try {
4605                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4606
4607                ActivityRecord rootR = r.task.getRootActivity();
4608                // Do not allow task to finish in Lock Task mode.
4609                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4610                    if (rootR == r) {
4611                        mStackSupervisor.showLockTaskToast();
4612                        return false;
4613                    }
4614                }
4615                boolean res = false;
4616                if (r != null) {
4617                    res = r.task.stack.finishActivityAffinityLocked(r);
4618                }
4619                return res;
4620            } finally {
4621                Binder.restoreCallingIdentity(origId);
4622            }
4623        }
4624    }
4625
4626    @Override
4627    public void finishVoiceTask(IVoiceInteractionSession session) {
4628        synchronized(this) {
4629            final long origId = Binder.clearCallingIdentity();
4630            try {
4631                mStackSupervisor.finishVoiceTask(session);
4632            } finally {
4633                Binder.restoreCallingIdentity(origId);
4634            }
4635        }
4636
4637    }
4638
4639    @Override
4640    public boolean releaseActivityInstance(IBinder token) {
4641        synchronized(this) {
4642            final long origId = Binder.clearCallingIdentity();
4643            try {
4644                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4645                if (r.task == null || r.task.stack == null) {
4646                    return false;
4647                }
4648                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4649            } finally {
4650                Binder.restoreCallingIdentity(origId);
4651            }
4652        }
4653    }
4654
4655    @Override
4656    public void releaseSomeActivities(IApplicationThread appInt) {
4657        synchronized(this) {
4658            final long origId = Binder.clearCallingIdentity();
4659            try {
4660                ProcessRecord app = getRecordForAppLocked(appInt);
4661                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4662            } finally {
4663                Binder.restoreCallingIdentity(origId);
4664            }
4665        }
4666    }
4667
4668    @Override
4669    public boolean willActivityBeVisible(IBinder token) {
4670        synchronized(this) {
4671            ActivityStack stack = ActivityRecord.getStackLocked(token);
4672            if (stack != null) {
4673                return stack.willActivityBeVisibleLocked(token);
4674            }
4675            return false;
4676        }
4677    }
4678
4679    @Override
4680    public void overridePendingTransition(IBinder token, String packageName,
4681            int enterAnim, int exitAnim) {
4682        synchronized(this) {
4683            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4684            if (self == null) {
4685                return;
4686            }
4687
4688            final long origId = Binder.clearCallingIdentity();
4689
4690            if (self.state == ActivityState.RESUMED
4691                    || self.state == ActivityState.PAUSING) {
4692                mWindowManager.overridePendingAppTransition(packageName,
4693                        enterAnim, exitAnim, null);
4694            }
4695
4696            Binder.restoreCallingIdentity(origId);
4697        }
4698    }
4699
4700    /**
4701     * Main function for removing an existing process from the activity manager
4702     * as a result of that process going away.  Clears out all connections
4703     * to the process.
4704     */
4705    private final void handleAppDiedLocked(ProcessRecord app,
4706            boolean restarting, boolean allowRestart) {
4707        int pid = app.pid;
4708        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4709        if (!kept && !restarting) {
4710            removeLruProcessLocked(app);
4711            if (pid > 0) {
4712                ProcessList.remove(pid);
4713            }
4714        }
4715
4716        if (mProfileProc == app) {
4717            clearProfilerLocked();
4718        }
4719
4720        // Remove this application's activities from active lists.
4721        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4722
4723        app.activities.clear();
4724
4725        if (app.instrumentationClass != null) {
4726            Slog.w(TAG, "Crash of app " + app.processName
4727                  + " running instrumentation " + app.instrumentationClass);
4728            Bundle info = new Bundle();
4729            info.putString("shortMsg", "Process crashed.");
4730            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4731        }
4732
4733        if (!restarting) {
4734            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4735                // If there was nothing to resume, and we are not already
4736                // restarting this process, but there is a visible activity that
4737                // is hosted by the process...  then make sure all visible
4738                // activities are running, taking care of restarting this
4739                // process.
4740                if (hasVisibleActivities) {
4741                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4742                }
4743            }
4744        }
4745    }
4746
4747    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4748        IBinder threadBinder = thread.asBinder();
4749        // Find the application record.
4750        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4751            ProcessRecord rec = mLruProcesses.get(i);
4752            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4753                return i;
4754            }
4755        }
4756        return -1;
4757    }
4758
4759    final ProcessRecord getRecordForAppLocked(
4760            IApplicationThread thread) {
4761        if (thread == null) {
4762            return null;
4763        }
4764
4765        int appIndex = getLRURecordIndexForAppLocked(thread);
4766        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4767    }
4768
4769    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4770        // If there are no longer any background processes running,
4771        // and the app that died was not running instrumentation,
4772        // then tell everyone we are now low on memory.
4773        boolean haveBg = false;
4774        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4775            ProcessRecord rec = mLruProcesses.get(i);
4776            if (rec.thread != null
4777                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4778                haveBg = true;
4779                break;
4780            }
4781        }
4782
4783        if (!haveBg) {
4784            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4785            if (doReport) {
4786                long now = SystemClock.uptimeMillis();
4787                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4788                    doReport = false;
4789                } else {
4790                    mLastMemUsageReportTime = now;
4791                }
4792            }
4793            final ArrayList<ProcessMemInfo> memInfos
4794                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4795            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4796            long now = SystemClock.uptimeMillis();
4797            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4798                ProcessRecord rec = mLruProcesses.get(i);
4799                if (rec == dyingProc || rec.thread == null) {
4800                    continue;
4801                }
4802                if (doReport) {
4803                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4804                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4805                }
4806                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4807                    // The low memory report is overriding any current
4808                    // state for a GC request.  Make sure to do
4809                    // heavy/important/visible/foreground processes first.
4810                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4811                        rec.lastRequestedGc = 0;
4812                    } else {
4813                        rec.lastRequestedGc = rec.lastLowMemory;
4814                    }
4815                    rec.reportLowMemory = true;
4816                    rec.lastLowMemory = now;
4817                    mProcessesToGc.remove(rec);
4818                    addProcessToGcListLocked(rec);
4819                }
4820            }
4821            if (doReport) {
4822                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4823                mHandler.sendMessage(msg);
4824            }
4825            scheduleAppGcsLocked();
4826        }
4827    }
4828
4829    final void appDiedLocked(ProcessRecord app) {
4830       appDiedLocked(app, app.pid, app.thread);
4831    }
4832
4833    final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4834        // First check if this ProcessRecord is actually active for the pid.
4835        synchronized (mPidsSelfLocked) {
4836            ProcessRecord curProc = mPidsSelfLocked.get(pid);
4837            if (curProc != app) {
4838                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4839                return;
4840            }
4841        }
4842
4843        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4844        synchronized (stats) {
4845            stats.noteProcessDiedLocked(app.info.uid, pid);
4846        }
4847
4848        Process.killProcessQuiet(pid);
4849        Process.killProcessGroup(app.info.uid, pid);
4850        app.killed = true;
4851
4852        // Clean up already done if the process has been re-started.
4853        if (app.pid == pid && app.thread != null &&
4854                app.thread.asBinder() == thread.asBinder()) {
4855            boolean doLowMem = app.instrumentationClass == null;
4856            boolean doOomAdj = doLowMem;
4857            if (!app.killedByAm) {
4858                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4859                        + ") has died");
4860                mAllowLowerMemLevel = true;
4861            } else {
4862                // Note that we always want to do oom adj to update our state with the
4863                // new number of procs.
4864                mAllowLowerMemLevel = false;
4865                doLowMem = false;
4866            }
4867            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4868            if (DEBUG_CLEANUP) Slog.v(
4869                TAG, "Dying app: " + app + ", pid: " + pid
4870                + ", thread: " + thread.asBinder());
4871            handleAppDiedLocked(app, false, true);
4872
4873            if (doOomAdj) {
4874                updateOomAdjLocked();
4875            }
4876            if (doLowMem) {
4877                doLowMemReportIfNeededLocked(app);
4878            }
4879        } else if (app.pid != pid) {
4880            // A new process has already been started.
4881            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4882                    + ") has died and restarted (pid " + app.pid + ").");
4883            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4884        } else if (DEBUG_PROCESSES) {
4885            Slog.d(TAG, "Received spurious death notification for thread "
4886                    + thread.asBinder());
4887        }
4888    }
4889
4890    /**
4891     * If a stack trace dump file is configured, dump process stack traces.
4892     * @param clearTraces causes the dump file to be erased prior to the new
4893     *    traces being written, if true; when false, the new traces will be
4894     *    appended to any existing file content.
4895     * @param firstPids of dalvik VM processes to dump stack traces for first
4896     * @param lastPids of dalvik VM processes to dump stack traces for last
4897     * @param nativeProcs optional list of native process names to dump stack crawls
4898     * @return file containing stack traces, or null if no dump file is configured
4899     */
4900    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4901            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4902        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4903        if (tracesPath == null || tracesPath.length() == 0) {
4904            return null;
4905        }
4906
4907        File tracesFile = new File(tracesPath);
4908        try {
4909            File tracesDir = tracesFile.getParentFile();
4910            if (!tracesDir.exists()) {
4911                tracesDir.mkdirs();
4912                if (!SELinux.restorecon(tracesDir)) {
4913                    return null;
4914                }
4915            }
4916            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4917
4918            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4919            tracesFile.createNewFile();
4920            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4921        } catch (IOException e) {
4922            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4923            return null;
4924        }
4925
4926        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4927        return tracesFile;
4928    }
4929
4930    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4931            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4932        // Use a FileObserver to detect when traces finish writing.
4933        // The order of traces is considered important to maintain for legibility.
4934        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4935            @Override
4936            public synchronized void onEvent(int event, String path) { notify(); }
4937        };
4938
4939        try {
4940            observer.startWatching();
4941
4942            // First collect all of the stacks of the most important pids.
4943            if (firstPids != null) {
4944                try {
4945                    int num = firstPids.size();
4946                    for (int i = 0; i < num; i++) {
4947                        synchronized (observer) {
4948                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4949                            observer.wait(200);  // Wait for write-close, give up after 200msec
4950                        }
4951                    }
4952                } catch (InterruptedException e) {
4953                    Log.wtf(TAG, e);
4954                }
4955            }
4956
4957            // Next collect the stacks of the native pids
4958            if (nativeProcs != null) {
4959                int[] pids = Process.getPidsForCommands(nativeProcs);
4960                if (pids != null) {
4961                    for (int pid : pids) {
4962                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4963                    }
4964                }
4965            }
4966
4967            // Lastly, measure CPU usage.
4968            if (processCpuTracker != null) {
4969                processCpuTracker.init();
4970                System.gc();
4971                processCpuTracker.update();
4972                try {
4973                    synchronized (processCpuTracker) {
4974                        processCpuTracker.wait(500); // measure over 1/2 second.
4975                    }
4976                } catch (InterruptedException e) {
4977                }
4978                processCpuTracker.update();
4979
4980                // We'll take the stack crawls of just the top apps using CPU.
4981                final int N = processCpuTracker.countWorkingStats();
4982                int numProcs = 0;
4983                for (int i=0; i<N && numProcs<5; i++) {
4984                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4985                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4986                        numProcs++;
4987                        try {
4988                            synchronized (observer) {
4989                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4990                                observer.wait(200);  // Wait for write-close, give up after 200msec
4991                            }
4992                        } catch (InterruptedException e) {
4993                            Log.wtf(TAG, e);
4994                        }
4995
4996                    }
4997                }
4998            }
4999        } finally {
5000            observer.stopWatching();
5001        }
5002    }
5003
5004    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5005        if (true || IS_USER_BUILD) {
5006            return;
5007        }
5008        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5009        if (tracesPath == null || tracesPath.length() == 0) {
5010            return;
5011        }
5012
5013        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5014        StrictMode.allowThreadDiskWrites();
5015        try {
5016            final File tracesFile = new File(tracesPath);
5017            final File tracesDir = tracesFile.getParentFile();
5018            final File tracesTmp = new File(tracesDir, "__tmp__");
5019            try {
5020                if (!tracesDir.exists()) {
5021                    tracesDir.mkdirs();
5022                    if (!SELinux.restorecon(tracesDir.getPath())) {
5023                        return;
5024                    }
5025                }
5026                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
5027
5028                if (tracesFile.exists()) {
5029                    tracesTmp.delete();
5030                    tracesFile.renameTo(tracesTmp);
5031                }
5032                StringBuilder sb = new StringBuilder();
5033                Time tobj = new Time();
5034                tobj.set(System.currentTimeMillis());
5035                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5036                sb.append(": ");
5037                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5038                sb.append(" since ");
5039                sb.append(msg);
5040                FileOutputStream fos = new FileOutputStream(tracesFile);
5041                fos.write(sb.toString().getBytes());
5042                if (app == null) {
5043                    fos.write("\n*** No application process!".getBytes());
5044                }
5045                fos.close();
5046                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5047            } catch (IOException e) {
5048                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5049                return;
5050            }
5051
5052            if (app != null) {
5053                ArrayList<Integer> firstPids = new ArrayList<Integer>();
5054                firstPids.add(app.pid);
5055                dumpStackTraces(tracesPath, firstPids, null, null, null);
5056            }
5057
5058            File lastTracesFile = null;
5059            File curTracesFile = null;
5060            for (int i=9; i>=0; i--) {
5061                String name = String.format(Locale.US, "slow%02d.txt", i);
5062                curTracesFile = new File(tracesDir, name);
5063                if (curTracesFile.exists()) {
5064                    if (lastTracesFile != null) {
5065                        curTracesFile.renameTo(lastTracesFile);
5066                    } else {
5067                        curTracesFile.delete();
5068                    }
5069                }
5070                lastTracesFile = curTracesFile;
5071            }
5072            tracesFile.renameTo(curTracesFile);
5073            if (tracesTmp.exists()) {
5074                tracesTmp.renameTo(tracesFile);
5075            }
5076        } finally {
5077            StrictMode.setThreadPolicy(oldPolicy);
5078        }
5079    }
5080
5081    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5082            ActivityRecord parent, boolean aboveSystem, final String annotation) {
5083        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5084        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5085
5086        if (mController != null) {
5087            try {
5088                // 0 == continue, -1 = kill process immediately
5089                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5090                if (res < 0 && app.pid != MY_PID) {
5091                    app.kill("anr", true);
5092                }
5093            } catch (RemoteException e) {
5094                mController = null;
5095                Watchdog.getInstance().setActivityController(null);
5096            }
5097        }
5098
5099        long anrTime = SystemClock.uptimeMillis();
5100        if (MONITOR_CPU_USAGE) {
5101            updateCpuStatsNow();
5102        }
5103
5104        synchronized (this) {
5105            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5106            if (mShuttingDown) {
5107                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5108                return;
5109            } else if (app.notResponding) {
5110                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5111                return;
5112            } else if (app.crashing) {
5113                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5114                return;
5115            }
5116
5117            // In case we come through here for the same app before completing
5118            // this one, mark as anring now so we will bail out.
5119            app.notResponding = true;
5120
5121            // Log the ANR to the event log.
5122            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5123                    app.processName, app.info.flags, annotation);
5124
5125            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5126            firstPids.add(app.pid);
5127
5128            int parentPid = app.pid;
5129            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5130            if (parentPid != app.pid) firstPids.add(parentPid);
5131
5132            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5133
5134            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5135                ProcessRecord r = mLruProcesses.get(i);
5136                if (r != null && r.thread != null) {
5137                    int pid = r.pid;
5138                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5139                        if (r.persistent) {
5140                            firstPids.add(pid);
5141                        } else {
5142                            lastPids.put(pid, Boolean.TRUE);
5143                        }
5144                    }
5145                }
5146            }
5147        }
5148
5149        // Log the ANR to the main log.
5150        StringBuilder info = new StringBuilder();
5151        info.setLength(0);
5152        info.append("ANR in ").append(app.processName);
5153        if (activity != null && activity.shortComponentName != null) {
5154            info.append(" (").append(activity.shortComponentName).append(")");
5155        }
5156        info.append("\n");
5157        info.append("PID: ").append(app.pid).append("\n");
5158        if (annotation != null) {
5159            info.append("Reason: ").append(annotation).append("\n");
5160        }
5161        if (parent != null && parent != activity) {
5162            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5163        }
5164
5165        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5166
5167        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5168                NATIVE_STACKS_OF_INTEREST);
5169
5170        String cpuInfo = null;
5171        if (MONITOR_CPU_USAGE) {
5172            updateCpuStatsNow();
5173            synchronized (mProcessCpuTracker) {
5174                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5175            }
5176            info.append(processCpuTracker.printCurrentLoad());
5177            info.append(cpuInfo);
5178        }
5179
5180        info.append(processCpuTracker.printCurrentState(anrTime));
5181
5182        Slog.e(TAG, info.toString());
5183        if (tracesFile == null) {
5184            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5185            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5186        }
5187
5188        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5189                cpuInfo, tracesFile, null);
5190
5191        if (mController != null) {
5192            try {
5193                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5194                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5195                if (res != 0) {
5196                    if (res < 0 && app.pid != MY_PID) {
5197                        app.kill("anr", true);
5198                    } else {
5199                        synchronized (this) {
5200                            mServices.scheduleServiceTimeoutLocked(app);
5201                        }
5202                    }
5203                    return;
5204                }
5205            } catch (RemoteException e) {
5206                mController = null;
5207                Watchdog.getInstance().setActivityController(null);
5208            }
5209        }
5210
5211        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5212        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5213                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5214
5215        synchronized (this) {
5216            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5217                app.kill("bg anr", true);
5218                return;
5219            }
5220
5221            // Set the app's notResponding state, and look up the errorReportReceiver
5222            makeAppNotRespondingLocked(app,
5223                    activity != null ? activity.shortComponentName : null,
5224                    annotation != null ? "ANR " + annotation : "ANR",
5225                    info.toString());
5226
5227            // Bring up the infamous App Not Responding dialog
5228            Message msg = Message.obtain();
5229            HashMap<String, Object> map = new HashMap<String, Object>();
5230            msg.what = SHOW_NOT_RESPONDING_MSG;
5231            msg.obj = map;
5232            msg.arg1 = aboveSystem ? 1 : 0;
5233            map.put("app", app);
5234            if (activity != null) {
5235                map.put("activity", activity);
5236            }
5237
5238            mHandler.sendMessage(msg);
5239        }
5240    }
5241
5242    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5243        if (!mLaunchWarningShown) {
5244            mLaunchWarningShown = true;
5245            mHandler.post(new Runnable() {
5246                @Override
5247                public void run() {
5248                    synchronized (ActivityManagerService.this) {
5249                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5250                        d.show();
5251                        mHandler.postDelayed(new Runnable() {
5252                            @Override
5253                            public void run() {
5254                                synchronized (ActivityManagerService.this) {
5255                                    d.dismiss();
5256                                    mLaunchWarningShown = false;
5257                                }
5258                            }
5259                        }, 4000);
5260                    }
5261                }
5262            });
5263        }
5264    }
5265
5266    @Override
5267    public boolean clearApplicationUserData(final String packageName,
5268            final IPackageDataObserver observer, int userId) {
5269        enforceNotIsolatedCaller("clearApplicationUserData");
5270        int uid = Binder.getCallingUid();
5271        int pid = Binder.getCallingPid();
5272        userId = handleIncomingUser(pid, uid,
5273                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5274        long callingId = Binder.clearCallingIdentity();
5275        try {
5276            IPackageManager pm = AppGlobals.getPackageManager();
5277            int pkgUid = -1;
5278            synchronized(this) {
5279                try {
5280                    pkgUid = pm.getPackageUid(packageName, userId);
5281                } catch (RemoteException e) {
5282                }
5283                if (pkgUid == -1) {
5284                    Slog.w(TAG, "Invalid packageName: " + packageName);
5285                    if (observer != null) {
5286                        try {
5287                            observer.onRemoveCompleted(packageName, false);
5288                        } catch (RemoteException e) {
5289                            Slog.i(TAG, "Observer no longer exists.");
5290                        }
5291                    }
5292                    return false;
5293                }
5294                if (uid == pkgUid || checkComponentPermission(
5295                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5296                        pid, uid, -1, true)
5297                        == PackageManager.PERMISSION_GRANTED) {
5298                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5299                } else {
5300                    throw new SecurityException("PID " + pid + " does not have permission "
5301                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5302                                    + " of package " + packageName);
5303                }
5304
5305                // Remove all tasks match the cleared application package and user
5306                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5307                    final TaskRecord tr = mRecentTasks.get(i);
5308                    final String taskPackageName =
5309                            tr.getBaseIntent().getComponent().getPackageName();
5310                    if (tr.userId != userId) continue;
5311                    if (!taskPackageName.equals(packageName)) continue;
5312                    removeTaskByIdLocked(tr.taskId, 0);
5313                }
5314            }
5315
5316            try {
5317                // Clear application user data
5318                pm.clearApplicationUserData(packageName, observer, userId);
5319
5320                synchronized(this) {
5321                    // Remove all permissions granted from/to this package
5322                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5323                }
5324
5325                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5326                        Uri.fromParts("package", packageName, null));
5327                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5328                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5329                        null, null, 0, null, null, null, false, false, userId);
5330            } catch (RemoteException e) {
5331            }
5332        } finally {
5333            Binder.restoreCallingIdentity(callingId);
5334        }
5335        return true;
5336    }
5337
5338    @Override
5339    public void killBackgroundProcesses(final String packageName, int userId) {
5340        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5341                != PackageManager.PERMISSION_GRANTED &&
5342                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5343                        != PackageManager.PERMISSION_GRANTED) {
5344            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5345                    + Binder.getCallingPid()
5346                    + ", uid=" + Binder.getCallingUid()
5347                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5348            Slog.w(TAG, msg);
5349            throw new SecurityException(msg);
5350        }
5351
5352        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5353                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5354        long callingId = Binder.clearCallingIdentity();
5355        try {
5356            IPackageManager pm = AppGlobals.getPackageManager();
5357            synchronized(this) {
5358                int appId = -1;
5359                try {
5360                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5361                } catch (RemoteException e) {
5362                }
5363                if (appId == -1) {
5364                    Slog.w(TAG, "Invalid packageName: " + packageName);
5365                    return;
5366                }
5367                killPackageProcessesLocked(packageName, appId, userId,
5368                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5369            }
5370        } finally {
5371            Binder.restoreCallingIdentity(callingId);
5372        }
5373    }
5374
5375    @Override
5376    public void killAllBackgroundProcesses() {
5377        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5378                != PackageManager.PERMISSION_GRANTED) {
5379            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5380                    + Binder.getCallingPid()
5381                    + ", uid=" + Binder.getCallingUid()
5382                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5383            Slog.w(TAG, msg);
5384            throw new SecurityException(msg);
5385        }
5386
5387        long callingId = Binder.clearCallingIdentity();
5388        try {
5389            synchronized(this) {
5390                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5391                final int NP = mProcessNames.getMap().size();
5392                for (int ip=0; ip<NP; ip++) {
5393                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5394                    final int NA = apps.size();
5395                    for (int ia=0; ia<NA; ia++) {
5396                        ProcessRecord app = apps.valueAt(ia);
5397                        if (app.persistent) {
5398                            // we don't kill persistent processes
5399                            continue;
5400                        }
5401                        if (app.removed) {
5402                            procs.add(app);
5403                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5404                            app.removed = true;
5405                            procs.add(app);
5406                        }
5407                    }
5408                }
5409
5410                int N = procs.size();
5411                for (int i=0; i<N; i++) {
5412                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5413                }
5414                mAllowLowerMemLevel = true;
5415                updateOomAdjLocked();
5416                doLowMemReportIfNeededLocked(null);
5417            }
5418        } finally {
5419            Binder.restoreCallingIdentity(callingId);
5420        }
5421    }
5422
5423    @Override
5424    public void forceStopPackage(final String packageName, int userId) {
5425        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5426                != PackageManager.PERMISSION_GRANTED) {
5427            String msg = "Permission Denial: forceStopPackage() from pid="
5428                    + Binder.getCallingPid()
5429                    + ", uid=" + Binder.getCallingUid()
5430                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5431            Slog.w(TAG, msg);
5432            throw new SecurityException(msg);
5433        }
5434        final int callingPid = Binder.getCallingPid();
5435        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5436                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5437        long callingId = Binder.clearCallingIdentity();
5438        try {
5439            IPackageManager pm = AppGlobals.getPackageManager();
5440            synchronized(this) {
5441                int[] users = userId == UserHandle.USER_ALL
5442                        ? getUsersLocked() : new int[] { userId };
5443                for (int user : users) {
5444                    int pkgUid = -1;
5445                    try {
5446                        pkgUid = pm.getPackageUid(packageName, user);
5447                    } catch (RemoteException e) {
5448                    }
5449                    if (pkgUid == -1) {
5450                        Slog.w(TAG, "Invalid packageName: " + packageName);
5451                        continue;
5452                    }
5453                    try {
5454                        pm.setPackageStoppedState(packageName, true, user);
5455                    } catch (RemoteException e) {
5456                    } catch (IllegalArgumentException e) {
5457                        Slog.w(TAG, "Failed trying to unstop package "
5458                                + packageName + ": " + e);
5459                    }
5460                    if (isUserRunningLocked(user, false)) {
5461                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5462                    }
5463                }
5464            }
5465        } finally {
5466            Binder.restoreCallingIdentity(callingId);
5467        }
5468    }
5469
5470    @Override
5471    public void addPackageDependency(String packageName) {
5472        synchronized (this) {
5473            int callingPid = Binder.getCallingPid();
5474            if (callingPid == Process.myPid()) {
5475                //  Yeah, um, no.
5476                Slog.w(TAG, "Can't addPackageDependency on system process");
5477                return;
5478            }
5479            ProcessRecord proc;
5480            synchronized (mPidsSelfLocked) {
5481                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5482            }
5483            if (proc != null) {
5484                if (proc.pkgDeps == null) {
5485                    proc.pkgDeps = new ArraySet<String>(1);
5486                }
5487                proc.pkgDeps.add(packageName);
5488            }
5489        }
5490    }
5491
5492    /*
5493     * The pkg name and app id have to be specified.
5494     */
5495    @Override
5496    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5497        if (pkg == null) {
5498            return;
5499        }
5500        // Make sure the uid is valid.
5501        if (appid < 0) {
5502            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5503            return;
5504        }
5505        int callerUid = Binder.getCallingUid();
5506        // Only the system server can kill an application
5507        if (callerUid == Process.SYSTEM_UID) {
5508            // Post an aysnc message to kill the application
5509            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5510            msg.arg1 = appid;
5511            msg.arg2 = 0;
5512            Bundle bundle = new Bundle();
5513            bundle.putString("pkg", pkg);
5514            bundle.putString("reason", reason);
5515            msg.obj = bundle;
5516            mHandler.sendMessage(msg);
5517        } else {
5518            throw new SecurityException(callerUid + " cannot kill pkg: " +
5519                    pkg);
5520        }
5521    }
5522
5523    @Override
5524    public void closeSystemDialogs(String reason) {
5525        enforceNotIsolatedCaller("closeSystemDialogs");
5526
5527        final int pid = Binder.getCallingPid();
5528        final int uid = Binder.getCallingUid();
5529        final long origId = Binder.clearCallingIdentity();
5530        try {
5531            synchronized (this) {
5532                // Only allow this from foreground processes, so that background
5533                // applications can't abuse it to prevent system UI from being shown.
5534                if (uid >= Process.FIRST_APPLICATION_UID) {
5535                    ProcessRecord proc;
5536                    synchronized (mPidsSelfLocked) {
5537                        proc = mPidsSelfLocked.get(pid);
5538                    }
5539                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5540                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5541                                + " from background process " + proc);
5542                        return;
5543                    }
5544                }
5545                closeSystemDialogsLocked(reason);
5546            }
5547        } finally {
5548            Binder.restoreCallingIdentity(origId);
5549        }
5550    }
5551
5552    void closeSystemDialogsLocked(String reason) {
5553        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5554        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5555                | Intent.FLAG_RECEIVER_FOREGROUND);
5556        if (reason != null) {
5557            intent.putExtra("reason", reason);
5558        }
5559        mWindowManager.closeSystemDialogs(reason);
5560
5561        mStackSupervisor.closeSystemDialogsLocked();
5562
5563        broadcastIntentLocked(null, null, intent, null,
5564                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5565                Process.SYSTEM_UID, UserHandle.USER_ALL);
5566    }
5567
5568    @Override
5569    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5570        enforceNotIsolatedCaller("getProcessMemoryInfo");
5571        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5572        for (int i=pids.length-1; i>=0; i--) {
5573            ProcessRecord proc;
5574            int oomAdj;
5575            synchronized (this) {
5576                synchronized (mPidsSelfLocked) {
5577                    proc = mPidsSelfLocked.get(pids[i]);
5578                    oomAdj = proc != null ? proc.setAdj : 0;
5579                }
5580            }
5581            infos[i] = new Debug.MemoryInfo();
5582            Debug.getMemoryInfo(pids[i], infos[i]);
5583            if (proc != null) {
5584                synchronized (this) {
5585                    if (proc.thread != null && proc.setAdj == oomAdj) {
5586                        // Record this for posterity if the process has been stable.
5587                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5588                                infos[i].getTotalUss(), false, proc.pkgList);
5589                    }
5590                }
5591            }
5592        }
5593        return infos;
5594    }
5595
5596    @Override
5597    public long[] getProcessPss(int[] pids) {
5598        enforceNotIsolatedCaller("getProcessPss");
5599        long[] pss = new long[pids.length];
5600        for (int i=pids.length-1; i>=0; i--) {
5601            ProcessRecord proc;
5602            int oomAdj;
5603            synchronized (this) {
5604                synchronized (mPidsSelfLocked) {
5605                    proc = mPidsSelfLocked.get(pids[i]);
5606                    oomAdj = proc != null ? proc.setAdj : 0;
5607                }
5608            }
5609            long[] tmpUss = new long[1];
5610            pss[i] = Debug.getPss(pids[i], tmpUss);
5611            if (proc != null) {
5612                synchronized (this) {
5613                    if (proc.thread != null && proc.setAdj == oomAdj) {
5614                        // Record this for posterity if the process has been stable.
5615                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5616                    }
5617                }
5618            }
5619        }
5620        return pss;
5621    }
5622
5623    @Override
5624    public void killApplicationProcess(String processName, int uid) {
5625        if (processName == null) {
5626            return;
5627        }
5628
5629        int callerUid = Binder.getCallingUid();
5630        // Only the system server can kill an application
5631        if (callerUid == Process.SYSTEM_UID) {
5632            synchronized (this) {
5633                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5634                if (app != null && app.thread != null) {
5635                    try {
5636                        app.thread.scheduleSuicide();
5637                    } catch (RemoteException e) {
5638                        // If the other end already died, then our work here is done.
5639                    }
5640                } else {
5641                    Slog.w(TAG, "Process/uid not found attempting kill of "
5642                            + processName + " / " + uid);
5643                }
5644            }
5645        } else {
5646            throw new SecurityException(callerUid + " cannot kill app process: " +
5647                    processName);
5648        }
5649    }
5650
5651    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5652        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5653                false, true, false, false, UserHandle.getUserId(uid), reason);
5654        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5655                Uri.fromParts("package", packageName, null));
5656        if (!mProcessesReady) {
5657            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5658                    | Intent.FLAG_RECEIVER_FOREGROUND);
5659        }
5660        intent.putExtra(Intent.EXTRA_UID, uid);
5661        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5662        broadcastIntentLocked(null, null, intent,
5663                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5664                false, false,
5665                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5666    }
5667
5668    private void forceStopUserLocked(int userId, String reason) {
5669        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5670        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5671        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5672                | Intent.FLAG_RECEIVER_FOREGROUND);
5673        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5674        broadcastIntentLocked(null, null, intent,
5675                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5676                false, false,
5677                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5678    }
5679
5680    private final boolean killPackageProcessesLocked(String packageName, int appId,
5681            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5682            boolean doit, boolean evenPersistent, String reason) {
5683        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5684
5685        // Remove all processes this package may have touched: all with the
5686        // same UID (except for the system or root user), and all whose name
5687        // matches the package name.
5688        final int NP = mProcessNames.getMap().size();
5689        for (int ip=0; ip<NP; ip++) {
5690            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5691            final int NA = apps.size();
5692            for (int ia=0; ia<NA; ia++) {
5693                ProcessRecord app = apps.valueAt(ia);
5694                if (app.persistent && !evenPersistent) {
5695                    // we don't kill persistent processes
5696                    continue;
5697                }
5698                if (app.removed) {
5699                    if (doit) {
5700                        procs.add(app);
5701                    }
5702                    continue;
5703                }
5704
5705                // Skip process if it doesn't meet our oom adj requirement.
5706                if (app.setAdj < minOomAdj) {
5707                    continue;
5708                }
5709
5710                // If no package is specified, we call all processes under the
5711                // give user id.
5712                if (packageName == null) {
5713                    if (app.userId != userId) {
5714                        continue;
5715                    }
5716                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5717                        continue;
5718                    }
5719                // Package has been specified, we want to hit all processes
5720                // that match it.  We need to qualify this by the processes
5721                // that are running under the specified app and user ID.
5722                } else {
5723                    final boolean isDep = app.pkgDeps != null
5724                            && app.pkgDeps.contains(packageName);
5725                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5726                        continue;
5727                    }
5728                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5729                        continue;
5730                    }
5731                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5732                        continue;
5733                    }
5734                }
5735
5736                // Process has passed all conditions, kill it!
5737                if (!doit) {
5738                    return true;
5739                }
5740                app.removed = true;
5741                procs.add(app);
5742            }
5743        }
5744
5745        int N = procs.size();
5746        for (int i=0; i<N; i++) {
5747            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5748        }
5749        updateOomAdjLocked();
5750        return N > 0;
5751    }
5752
5753    private final boolean forceStopPackageLocked(String name, int appId,
5754            boolean callerWillRestart, boolean purgeCache, boolean doit,
5755            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5756        int i;
5757        int N;
5758
5759        if (userId == UserHandle.USER_ALL && name == null) {
5760            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5761        }
5762
5763        if (appId < 0 && name != null) {
5764            try {
5765                appId = UserHandle.getAppId(
5766                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5767            } catch (RemoteException e) {
5768            }
5769        }
5770
5771        if (doit) {
5772            if (name != null) {
5773                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5774                        + " user=" + userId + ": " + reason);
5775            } else {
5776                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5777            }
5778
5779            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5780            for (int ip=pmap.size()-1; ip>=0; ip--) {
5781                SparseArray<Long> ba = pmap.valueAt(ip);
5782                for (i=ba.size()-1; i>=0; i--) {
5783                    boolean remove = false;
5784                    final int entUid = ba.keyAt(i);
5785                    if (name != null) {
5786                        if (userId == UserHandle.USER_ALL) {
5787                            if (UserHandle.getAppId(entUid) == appId) {
5788                                remove = true;
5789                            }
5790                        } else {
5791                            if (entUid == UserHandle.getUid(userId, appId)) {
5792                                remove = true;
5793                            }
5794                        }
5795                    } else if (UserHandle.getUserId(entUid) == userId) {
5796                        remove = true;
5797                    }
5798                    if (remove) {
5799                        ba.removeAt(i);
5800                    }
5801                }
5802                if (ba.size() == 0) {
5803                    pmap.removeAt(ip);
5804                }
5805            }
5806        }
5807
5808        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5809                -100, callerWillRestart, true, doit, evenPersistent,
5810                name == null ? ("stop user " + userId) : ("stop " + name));
5811
5812        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5813            if (!doit) {
5814                return true;
5815            }
5816            didSomething = true;
5817        }
5818
5819        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5820            if (!doit) {
5821                return true;
5822            }
5823            didSomething = true;
5824        }
5825
5826        if (name == null) {
5827            // Remove all sticky broadcasts from this user.
5828            mStickyBroadcasts.remove(userId);
5829        }
5830
5831        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5832        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5833                userId, providers)) {
5834            if (!doit) {
5835                return true;
5836            }
5837            didSomething = true;
5838        }
5839        N = providers.size();
5840        for (i=0; i<N; i++) {
5841            removeDyingProviderLocked(null, providers.get(i), true);
5842        }
5843
5844        // Remove transient permissions granted from/to this package/user
5845        removeUriPermissionsForPackageLocked(name, userId, false);
5846
5847        if (name == null || uninstalling) {
5848            // Remove pending intents.  For now we only do this when force
5849            // stopping users, because we have some problems when doing this
5850            // for packages -- app widgets are not currently cleaned up for
5851            // such packages, so they can be left with bad pending intents.
5852            if (mIntentSenderRecords.size() > 0) {
5853                Iterator<WeakReference<PendingIntentRecord>> it
5854                        = mIntentSenderRecords.values().iterator();
5855                while (it.hasNext()) {
5856                    WeakReference<PendingIntentRecord> wpir = it.next();
5857                    if (wpir == null) {
5858                        it.remove();
5859                        continue;
5860                    }
5861                    PendingIntentRecord pir = wpir.get();
5862                    if (pir == null) {
5863                        it.remove();
5864                        continue;
5865                    }
5866                    if (name == null) {
5867                        // Stopping user, remove all objects for the user.
5868                        if (pir.key.userId != userId) {
5869                            // Not the same user, skip it.
5870                            continue;
5871                        }
5872                    } else {
5873                        if (UserHandle.getAppId(pir.uid) != appId) {
5874                            // Different app id, skip it.
5875                            continue;
5876                        }
5877                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5878                            // Different user, skip it.
5879                            continue;
5880                        }
5881                        if (!pir.key.packageName.equals(name)) {
5882                            // Different package, skip it.
5883                            continue;
5884                        }
5885                    }
5886                    if (!doit) {
5887                        return true;
5888                    }
5889                    didSomething = true;
5890                    it.remove();
5891                    pir.canceled = true;
5892                    if (pir.key.activity != null) {
5893                        pir.key.activity.pendingResults.remove(pir.ref);
5894                    }
5895                }
5896            }
5897        }
5898
5899        if (doit) {
5900            if (purgeCache && name != null) {
5901                AttributeCache ac = AttributeCache.instance();
5902                if (ac != null) {
5903                    ac.removePackage(name);
5904                }
5905            }
5906            if (mBooted) {
5907                mStackSupervisor.resumeTopActivitiesLocked();
5908                mStackSupervisor.scheduleIdleLocked();
5909            }
5910        }
5911
5912        return didSomething;
5913    }
5914
5915    private final boolean removeProcessLocked(ProcessRecord app,
5916            boolean callerWillRestart, boolean allowRestart, String reason) {
5917        final String name = app.processName;
5918        final int uid = app.uid;
5919        if (DEBUG_PROCESSES) Slog.d(
5920            TAG, "Force removing proc " + app.toShortString() + " (" + name
5921            + "/" + uid + ")");
5922
5923        mProcessNames.remove(name, uid);
5924        mIsolatedProcesses.remove(app.uid);
5925        if (mHeavyWeightProcess == app) {
5926            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5927                    mHeavyWeightProcess.userId, 0));
5928            mHeavyWeightProcess = null;
5929        }
5930        boolean needRestart = false;
5931        if (app.pid > 0 && app.pid != MY_PID) {
5932            int pid = app.pid;
5933            synchronized (mPidsSelfLocked) {
5934                mPidsSelfLocked.remove(pid);
5935                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5936            }
5937            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5938            if (app.isolated) {
5939                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5940            }
5941            app.kill(reason, true);
5942            handleAppDiedLocked(app, true, allowRestart);
5943            removeLruProcessLocked(app);
5944
5945            if (app.persistent && !app.isolated) {
5946                if (!callerWillRestart) {
5947                    addAppLocked(app.info, false, null /* ABI override */);
5948                } else {
5949                    needRestart = true;
5950                }
5951            }
5952        } else {
5953            mRemovedProcesses.add(app);
5954        }
5955
5956        return needRestart;
5957    }
5958
5959    private final void processStartTimedOutLocked(ProcessRecord app) {
5960        final int pid = app.pid;
5961        boolean gone = false;
5962        synchronized (mPidsSelfLocked) {
5963            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5964            if (knownApp != null && knownApp.thread == null) {
5965                mPidsSelfLocked.remove(pid);
5966                gone = true;
5967            }
5968        }
5969
5970        if (gone) {
5971            Slog.w(TAG, "Process " + app + " failed to attach");
5972            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5973                    pid, app.uid, app.processName);
5974            mProcessNames.remove(app.processName, app.uid);
5975            mIsolatedProcesses.remove(app.uid);
5976            if (mHeavyWeightProcess == app) {
5977                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5978                        mHeavyWeightProcess.userId, 0));
5979                mHeavyWeightProcess = null;
5980            }
5981            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5982            if (app.isolated) {
5983                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5984            }
5985            // Take care of any launching providers waiting for this process.
5986            checkAppInLaunchingProvidersLocked(app, true);
5987            // Take care of any services that are waiting for the process.
5988            mServices.processStartTimedOutLocked(app);
5989            app.kill("start timeout", true);
5990            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5991                Slog.w(TAG, "Unattached app died before backup, skipping");
5992                try {
5993                    IBackupManager bm = IBackupManager.Stub.asInterface(
5994                            ServiceManager.getService(Context.BACKUP_SERVICE));
5995                    bm.agentDisconnected(app.info.packageName);
5996                } catch (RemoteException e) {
5997                    // Can't happen; the backup manager is local
5998                }
5999            }
6000            if (isPendingBroadcastProcessLocked(pid)) {
6001                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6002                skipPendingBroadcastLocked(pid);
6003            }
6004        } else {
6005            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6006        }
6007    }
6008
6009    private final boolean attachApplicationLocked(IApplicationThread thread,
6010            int pid) {
6011
6012        // Find the application record that is being attached...  either via
6013        // the pid if we are running in multiple processes, or just pull the
6014        // next app record if we are emulating process with anonymous threads.
6015        ProcessRecord app;
6016        if (pid != MY_PID && pid >= 0) {
6017            synchronized (mPidsSelfLocked) {
6018                app = mPidsSelfLocked.get(pid);
6019            }
6020        } else {
6021            app = null;
6022        }
6023
6024        if (app == null) {
6025            Slog.w(TAG, "No pending application record for pid " + pid
6026                    + " (IApplicationThread " + thread + "); dropping process");
6027            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6028            if (pid > 0 && pid != MY_PID) {
6029                Process.killProcessQuiet(pid);
6030                //TODO: Process.killProcessGroup(app.info.uid, pid);
6031            } else {
6032                try {
6033                    thread.scheduleExit();
6034                } catch (Exception e) {
6035                    // Ignore exceptions.
6036                }
6037            }
6038            return false;
6039        }
6040
6041        // If this application record is still attached to a previous
6042        // process, clean it up now.
6043        if (app.thread != null) {
6044            handleAppDiedLocked(app, true, true);
6045        }
6046
6047        // Tell the process all about itself.
6048
6049        if (localLOGV) Slog.v(
6050                TAG, "Binding process pid " + pid + " to record " + app);
6051
6052        final String processName = app.processName;
6053        try {
6054            AppDeathRecipient adr = new AppDeathRecipient(
6055                    app, pid, thread);
6056            thread.asBinder().linkToDeath(adr, 0);
6057            app.deathRecipient = adr;
6058        } catch (RemoteException e) {
6059            app.resetPackageList(mProcessStats);
6060            startProcessLocked(app, "link fail", processName);
6061            return false;
6062        }
6063
6064        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6065
6066        app.makeActive(thread, mProcessStats);
6067        app.curAdj = app.setAdj = -100;
6068        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6069        app.forcingToForeground = null;
6070        updateProcessForegroundLocked(app, false, false);
6071        app.hasShownUi = false;
6072        app.debugging = false;
6073        app.cached = false;
6074
6075        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6076
6077        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6078        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6079
6080        if (!normalMode) {
6081            Slog.i(TAG, "Launching preboot mode app: " + app);
6082        }
6083
6084        if (localLOGV) Slog.v(
6085            TAG, "New app record " + app
6086            + " thread=" + thread.asBinder() + " pid=" + pid);
6087        try {
6088            int testMode = IApplicationThread.DEBUG_OFF;
6089            if (mDebugApp != null && mDebugApp.equals(processName)) {
6090                testMode = mWaitForDebugger
6091                    ? IApplicationThread.DEBUG_WAIT
6092                    : IApplicationThread.DEBUG_ON;
6093                app.debugging = true;
6094                if (mDebugTransient) {
6095                    mDebugApp = mOrigDebugApp;
6096                    mWaitForDebugger = mOrigWaitForDebugger;
6097                }
6098            }
6099            String profileFile = app.instrumentationProfileFile;
6100            ParcelFileDescriptor profileFd = null;
6101            int samplingInterval = 0;
6102            boolean profileAutoStop = false;
6103            if (mProfileApp != null && mProfileApp.equals(processName)) {
6104                mProfileProc = app;
6105                profileFile = mProfileFile;
6106                profileFd = mProfileFd;
6107                samplingInterval = mSamplingInterval;
6108                profileAutoStop = mAutoStopProfiler;
6109            }
6110            boolean enableOpenGlTrace = false;
6111            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6112                enableOpenGlTrace = true;
6113                mOpenGlTraceApp = null;
6114            }
6115
6116            // If the app is being launched for restore or full backup, set it up specially
6117            boolean isRestrictedBackupMode = false;
6118            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6119                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6120                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6121                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6122            }
6123
6124            ensurePackageDexOpt(app.instrumentationInfo != null
6125                    ? app.instrumentationInfo.packageName
6126                    : app.info.packageName);
6127            if (app.instrumentationClass != null) {
6128                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6129            }
6130            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6131                    + processName + " with config " + mConfiguration);
6132            ApplicationInfo appInfo = app.instrumentationInfo != null
6133                    ? app.instrumentationInfo : app.info;
6134            app.compat = compatibilityInfoForPackageLocked(appInfo);
6135            if (profileFd != null) {
6136                profileFd = profileFd.dup();
6137            }
6138            ProfilerInfo profilerInfo = profileFile == null ? null
6139                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6140            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6141                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6142                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6143                    isRestrictedBackupMode || !normalMode, app.persistent,
6144                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6145                    mCoreSettingsObserver.getCoreSettingsLocked());
6146            updateLruProcessLocked(app, false, null);
6147            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6148        } catch (Exception e) {
6149            // todo: Yikes!  What should we do?  For now we will try to
6150            // start another process, but that could easily get us in
6151            // an infinite loop of restarting processes...
6152            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6153
6154            app.resetPackageList(mProcessStats);
6155            app.unlinkDeathRecipient();
6156            startProcessLocked(app, "bind fail", processName);
6157            return false;
6158        }
6159
6160        // Remove this record from the list of starting applications.
6161        mPersistentStartingProcesses.remove(app);
6162        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6163                "Attach application locked removing on hold: " + app);
6164        mProcessesOnHold.remove(app);
6165
6166        boolean badApp = false;
6167        boolean didSomething = false;
6168
6169        // See if the top visible activity is waiting to run in this process...
6170        if (normalMode) {
6171            try {
6172                if (mStackSupervisor.attachApplicationLocked(app)) {
6173                    didSomething = true;
6174                }
6175            } catch (Exception e) {
6176                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6177                badApp = true;
6178            }
6179        }
6180
6181        // Find any services that should be running in this process...
6182        if (!badApp) {
6183            try {
6184                didSomething |= mServices.attachApplicationLocked(app, processName);
6185            } catch (Exception e) {
6186                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6187                badApp = true;
6188            }
6189        }
6190
6191        // Check if a next-broadcast receiver is in this process...
6192        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6193            try {
6194                didSomething |= sendPendingBroadcastsLocked(app);
6195            } catch (Exception e) {
6196                // If the app died trying to launch the receiver we declare it 'bad'
6197                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6198                badApp = true;
6199            }
6200        }
6201
6202        // Check whether the next backup agent is in this process...
6203        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6204            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6205            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6206            try {
6207                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6208                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6209                        mBackupTarget.backupMode);
6210            } catch (Exception e) {
6211                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6212                badApp = true;
6213            }
6214        }
6215
6216        if (badApp) {
6217            app.kill("error during init", true);
6218            handleAppDiedLocked(app, false, true);
6219            return false;
6220        }
6221
6222        if (!didSomething) {
6223            updateOomAdjLocked();
6224        }
6225
6226        return true;
6227    }
6228
6229    @Override
6230    public final void attachApplication(IApplicationThread thread) {
6231        synchronized (this) {
6232            int callingPid = Binder.getCallingPid();
6233            final long origId = Binder.clearCallingIdentity();
6234            attachApplicationLocked(thread, callingPid);
6235            Binder.restoreCallingIdentity(origId);
6236        }
6237    }
6238
6239    @Override
6240    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6241        final long origId = Binder.clearCallingIdentity();
6242        synchronized (this) {
6243            ActivityStack stack = ActivityRecord.getStackLocked(token);
6244            if (stack != null) {
6245                ActivityRecord r =
6246                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6247                if (stopProfiling) {
6248                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6249                        try {
6250                            mProfileFd.close();
6251                        } catch (IOException e) {
6252                        }
6253                        clearProfilerLocked();
6254                    }
6255                }
6256            }
6257        }
6258        Binder.restoreCallingIdentity(origId);
6259    }
6260
6261    void postEnableScreenAfterBootLocked() {
6262        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6263    }
6264
6265    void enableScreenAfterBoot() {
6266        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6267                SystemClock.uptimeMillis());
6268        mWindowManager.enableScreenAfterBoot();
6269
6270        synchronized (this) {
6271            updateEventDispatchingLocked();
6272        }
6273    }
6274
6275    @Override
6276    public void showBootMessage(final CharSequence msg, final boolean always) {
6277        enforceNotIsolatedCaller("showBootMessage");
6278        mWindowManager.showBootMessage(msg, always);
6279    }
6280
6281    @Override
6282    public void keyguardWaitingForActivityDrawn() {
6283        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6284        final long token = Binder.clearCallingIdentity();
6285        try {
6286            synchronized (this) {
6287                if (DEBUG_LOCKSCREEN) logLockScreen("");
6288                mWindowManager.keyguardWaitingForActivityDrawn();
6289                if (mLockScreenShown) {
6290                    mLockScreenShown = false;
6291                    comeOutOfSleepIfNeededLocked();
6292                }
6293            }
6294        } finally {
6295            Binder.restoreCallingIdentity(token);
6296        }
6297    }
6298
6299    final void finishBooting() {
6300        synchronized (this) {
6301            if (!mBootAnimationComplete) {
6302                mCallFinishBooting = true;
6303                return;
6304            }
6305            mCallFinishBooting = false;
6306        }
6307
6308        // Register receivers to handle package update events
6309        mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6310
6311        // Let system services know.
6312        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6313
6314        synchronized (this) {
6315            // Ensure that any processes we had put on hold are now started
6316            // up.
6317            final int NP = mProcessesOnHold.size();
6318            if (NP > 0) {
6319                ArrayList<ProcessRecord> procs =
6320                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6321                for (int ip=0; ip<NP; ip++) {
6322                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6323                            + procs.get(ip));
6324                    startProcessLocked(procs.get(ip), "on-hold", null);
6325                }
6326            }
6327
6328            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6329                // Start looking for apps that are abusing wake locks.
6330                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6331                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6332                // Tell anyone interested that we are done booting!
6333                SystemProperties.set("sys.boot_completed", "1");
6334
6335                // And trigger dev.bootcomplete if we are not showing encryption progress
6336                if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6337                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6338                    SystemProperties.set("dev.bootcomplete", "1");
6339                }
6340                for (int i=0; i<mStartedUsers.size(); i++) {
6341                    UserStartedState uss = mStartedUsers.valueAt(i);
6342                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6343                        uss.mState = UserStartedState.STATE_RUNNING;
6344                        final int userId = mStartedUsers.keyAt(i);
6345                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6346                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6347                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6348                        broadcastIntentLocked(null, null, intent, null,
6349                                new IIntentReceiver.Stub() {
6350                                    @Override
6351                                    public void performReceive(Intent intent, int resultCode,
6352                                            String data, Bundle extras, boolean ordered,
6353                                            boolean sticky, int sendingUser) {
6354                                        synchronized (ActivityManagerService.this) {
6355                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6356                                                    true, false);
6357                                        }
6358                                    }
6359                                },
6360                                0, null, null,
6361                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6362                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6363                                userId);
6364                    }
6365                }
6366                scheduleStartProfilesLocked();
6367            }
6368        }
6369    }
6370
6371    @Override
6372    public void bootAnimationComplete() {
6373        final boolean callFinishBooting;
6374        synchronized (this) {
6375            callFinishBooting = mCallFinishBooting;
6376            mBootAnimationComplete = true;
6377        }
6378        if (callFinishBooting) {
6379            finishBooting();
6380        }
6381    }
6382
6383    final void ensureBootCompleted() {
6384        boolean booting;
6385        boolean enableScreen;
6386        synchronized (this) {
6387            booting = mBooting;
6388            mBooting = false;
6389            enableScreen = !mBooted;
6390            mBooted = true;
6391        }
6392
6393        if (booting) {
6394            finishBooting();
6395        }
6396
6397        if (enableScreen) {
6398            enableScreenAfterBoot();
6399        }
6400    }
6401
6402    @Override
6403    public final void activityResumed(IBinder token) {
6404        final long origId = Binder.clearCallingIdentity();
6405        synchronized(this) {
6406            ActivityStack stack = ActivityRecord.getStackLocked(token);
6407            if (stack != null) {
6408                ActivityRecord.activityResumedLocked(token);
6409            }
6410        }
6411        Binder.restoreCallingIdentity(origId);
6412    }
6413
6414    @Override
6415    public final void activityPaused(IBinder token) {
6416        final long origId = Binder.clearCallingIdentity();
6417        synchronized(this) {
6418            ActivityStack stack = ActivityRecord.getStackLocked(token);
6419            if (stack != null) {
6420                stack.activityPausedLocked(token, false);
6421            }
6422        }
6423        Binder.restoreCallingIdentity(origId);
6424    }
6425
6426    @Override
6427    public final void activityStopped(IBinder token, Bundle icicle,
6428            PersistableBundle persistentState, CharSequence description) {
6429        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6430
6431        // Refuse possible leaked file descriptors
6432        if (icicle != null && icicle.hasFileDescriptors()) {
6433            throw new IllegalArgumentException("File descriptors passed in Bundle");
6434        }
6435
6436        final long origId = Binder.clearCallingIdentity();
6437
6438        synchronized (this) {
6439            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6440            if (r != null) {
6441                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6442            }
6443        }
6444
6445        trimApplications();
6446
6447        Binder.restoreCallingIdentity(origId);
6448    }
6449
6450    @Override
6451    public final void activityDestroyed(IBinder token) {
6452        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6453        synchronized (this) {
6454            ActivityStack stack = ActivityRecord.getStackLocked(token);
6455            if (stack != null) {
6456                stack.activityDestroyedLocked(token);
6457            }
6458        }
6459    }
6460
6461    @Override
6462    public final void backgroundResourcesReleased(IBinder token) {
6463        final long origId = Binder.clearCallingIdentity();
6464        try {
6465            synchronized (this) {
6466                ActivityStack stack = ActivityRecord.getStackLocked(token);
6467                if (stack != null) {
6468                    stack.backgroundResourcesReleased(token);
6469                }
6470            }
6471        } finally {
6472            Binder.restoreCallingIdentity(origId);
6473        }
6474    }
6475
6476    @Override
6477    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6478        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6479    }
6480
6481    @Override
6482    public final void notifyEnterAnimationComplete(IBinder token) {
6483        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6484    }
6485
6486    @Override
6487    public String getCallingPackage(IBinder token) {
6488        synchronized (this) {
6489            ActivityRecord r = getCallingRecordLocked(token);
6490            return r != null ? r.info.packageName : null;
6491        }
6492    }
6493
6494    @Override
6495    public ComponentName getCallingActivity(IBinder token) {
6496        synchronized (this) {
6497            ActivityRecord r = getCallingRecordLocked(token);
6498            return r != null ? r.intent.getComponent() : null;
6499        }
6500    }
6501
6502    private ActivityRecord getCallingRecordLocked(IBinder token) {
6503        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6504        if (r == null) {
6505            return null;
6506        }
6507        return r.resultTo;
6508    }
6509
6510    @Override
6511    public ComponentName getActivityClassForToken(IBinder token) {
6512        synchronized(this) {
6513            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6514            if (r == null) {
6515                return null;
6516            }
6517            return r.intent.getComponent();
6518        }
6519    }
6520
6521    @Override
6522    public String getPackageForToken(IBinder token) {
6523        synchronized(this) {
6524            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6525            if (r == null) {
6526                return null;
6527            }
6528            return r.packageName;
6529        }
6530    }
6531
6532    @Override
6533    public IIntentSender getIntentSender(int type,
6534            String packageName, IBinder token, String resultWho,
6535            int requestCode, Intent[] intents, String[] resolvedTypes,
6536            int flags, Bundle options, int userId) {
6537        enforceNotIsolatedCaller("getIntentSender");
6538        // Refuse possible leaked file descriptors
6539        if (intents != null) {
6540            if (intents.length < 1) {
6541                throw new IllegalArgumentException("Intents array length must be >= 1");
6542            }
6543            for (int i=0; i<intents.length; i++) {
6544                Intent intent = intents[i];
6545                if (intent != null) {
6546                    if (intent.hasFileDescriptors()) {
6547                        throw new IllegalArgumentException("File descriptors passed in Intent");
6548                    }
6549                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6550                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6551                        throw new IllegalArgumentException(
6552                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6553                    }
6554                    intents[i] = new Intent(intent);
6555                }
6556            }
6557            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6558                throw new IllegalArgumentException(
6559                        "Intent array length does not match resolvedTypes length");
6560            }
6561        }
6562        if (options != null) {
6563            if (options.hasFileDescriptors()) {
6564                throw new IllegalArgumentException("File descriptors passed in options");
6565            }
6566        }
6567
6568        synchronized(this) {
6569            int callingUid = Binder.getCallingUid();
6570            int origUserId = userId;
6571            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6572                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6573                    ALLOW_NON_FULL, "getIntentSender", null);
6574            if (origUserId == UserHandle.USER_CURRENT) {
6575                // We don't want to evaluate this until the pending intent is
6576                // actually executed.  However, we do want to always do the
6577                // security checking for it above.
6578                userId = UserHandle.USER_CURRENT;
6579            }
6580            try {
6581                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6582                    int uid = AppGlobals.getPackageManager()
6583                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6584                    if (!UserHandle.isSameApp(callingUid, uid)) {
6585                        String msg = "Permission Denial: getIntentSender() from pid="
6586                            + Binder.getCallingPid()
6587                            + ", uid=" + Binder.getCallingUid()
6588                            + ", (need uid=" + uid + ")"
6589                            + " is not allowed to send as package " + packageName;
6590                        Slog.w(TAG, msg);
6591                        throw new SecurityException(msg);
6592                    }
6593                }
6594
6595                return getIntentSenderLocked(type, packageName, callingUid, userId,
6596                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6597
6598            } catch (RemoteException e) {
6599                throw new SecurityException(e);
6600            }
6601        }
6602    }
6603
6604    IIntentSender getIntentSenderLocked(int type, String packageName,
6605            int callingUid, int userId, IBinder token, String resultWho,
6606            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6607            Bundle options) {
6608        if (DEBUG_MU)
6609            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6610        ActivityRecord activity = null;
6611        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6612            activity = ActivityRecord.isInStackLocked(token);
6613            if (activity == null) {
6614                return null;
6615            }
6616            if (activity.finishing) {
6617                return null;
6618            }
6619        }
6620
6621        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6622        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6623        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6624        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6625                |PendingIntent.FLAG_UPDATE_CURRENT);
6626
6627        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6628                type, packageName, activity, resultWho,
6629                requestCode, intents, resolvedTypes, flags, options, userId);
6630        WeakReference<PendingIntentRecord> ref;
6631        ref = mIntentSenderRecords.get(key);
6632        PendingIntentRecord rec = ref != null ? ref.get() : null;
6633        if (rec != null) {
6634            if (!cancelCurrent) {
6635                if (updateCurrent) {
6636                    if (rec.key.requestIntent != null) {
6637                        rec.key.requestIntent.replaceExtras(intents != null ?
6638                                intents[intents.length - 1] : null);
6639                    }
6640                    if (intents != null) {
6641                        intents[intents.length-1] = rec.key.requestIntent;
6642                        rec.key.allIntents = intents;
6643                        rec.key.allResolvedTypes = resolvedTypes;
6644                    } else {
6645                        rec.key.allIntents = null;
6646                        rec.key.allResolvedTypes = null;
6647                    }
6648                }
6649                return rec;
6650            }
6651            rec.canceled = true;
6652            mIntentSenderRecords.remove(key);
6653        }
6654        if (noCreate) {
6655            return rec;
6656        }
6657        rec = new PendingIntentRecord(this, key, callingUid);
6658        mIntentSenderRecords.put(key, rec.ref);
6659        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6660            if (activity.pendingResults == null) {
6661                activity.pendingResults
6662                        = new HashSet<WeakReference<PendingIntentRecord>>();
6663            }
6664            activity.pendingResults.add(rec.ref);
6665        }
6666        return rec;
6667    }
6668
6669    @Override
6670    public void cancelIntentSender(IIntentSender sender) {
6671        if (!(sender instanceof PendingIntentRecord)) {
6672            return;
6673        }
6674        synchronized(this) {
6675            PendingIntentRecord rec = (PendingIntentRecord)sender;
6676            try {
6677                int uid = AppGlobals.getPackageManager()
6678                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6679                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6680                    String msg = "Permission Denial: cancelIntentSender() from pid="
6681                        + Binder.getCallingPid()
6682                        + ", uid=" + Binder.getCallingUid()
6683                        + " is not allowed to cancel packges "
6684                        + rec.key.packageName;
6685                    Slog.w(TAG, msg);
6686                    throw new SecurityException(msg);
6687                }
6688            } catch (RemoteException e) {
6689                throw new SecurityException(e);
6690            }
6691            cancelIntentSenderLocked(rec, true);
6692        }
6693    }
6694
6695    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6696        rec.canceled = true;
6697        mIntentSenderRecords.remove(rec.key);
6698        if (cleanActivity && rec.key.activity != null) {
6699            rec.key.activity.pendingResults.remove(rec.ref);
6700        }
6701    }
6702
6703    @Override
6704    public String getPackageForIntentSender(IIntentSender pendingResult) {
6705        if (!(pendingResult instanceof PendingIntentRecord)) {
6706            return null;
6707        }
6708        try {
6709            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6710            return res.key.packageName;
6711        } catch (ClassCastException e) {
6712        }
6713        return null;
6714    }
6715
6716    @Override
6717    public int getUidForIntentSender(IIntentSender sender) {
6718        if (sender instanceof PendingIntentRecord) {
6719            try {
6720                PendingIntentRecord res = (PendingIntentRecord)sender;
6721                return res.uid;
6722            } catch (ClassCastException e) {
6723            }
6724        }
6725        return -1;
6726    }
6727
6728    @Override
6729    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6730        if (!(pendingResult instanceof PendingIntentRecord)) {
6731            return false;
6732        }
6733        try {
6734            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6735            if (res.key.allIntents == null) {
6736                return false;
6737            }
6738            for (int i=0; i<res.key.allIntents.length; i++) {
6739                Intent intent = res.key.allIntents[i];
6740                if (intent.getPackage() != null && intent.getComponent() != null) {
6741                    return false;
6742                }
6743            }
6744            return true;
6745        } catch (ClassCastException e) {
6746        }
6747        return false;
6748    }
6749
6750    @Override
6751    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6752        if (!(pendingResult instanceof PendingIntentRecord)) {
6753            return false;
6754        }
6755        try {
6756            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6757            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6758                return true;
6759            }
6760            return false;
6761        } catch (ClassCastException e) {
6762        }
6763        return false;
6764    }
6765
6766    @Override
6767    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6768        if (!(pendingResult instanceof PendingIntentRecord)) {
6769            return null;
6770        }
6771        try {
6772            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6773            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6774        } catch (ClassCastException e) {
6775        }
6776        return null;
6777    }
6778
6779    @Override
6780    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6781        if (!(pendingResult instanceof PendingIntentRecord)) {
6782            return null;
6783        }
6784        try {
6785            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6786            Intent intent = res.key.requestIntent;
6787            if (intent != null) {
6788                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6789                        || res.lastTagPrefix.equals(prefix))) {
6790                    return res.lastTag;
6791                }
6792                res.lastTagPrefix = prefix;
6793                StringBuilder sb = new StringBuilder(128);
6794                if (prefix != null) {
6795                    sb.append(prefix);
6796                }
6797                if (intent.getAction() != null) {
6798                    sb.append(intent.getAction());
6799                } else if (intent.getComponent() != null) {
6800                    intent.getComponent().appendShortString(sb);
6801                } else {
6802                    sb.append("?");
6803                }
6804                return res.lastTag = sb.toString();
6805            }
6806        } catch (ClassCastException e) {
6807        }
6808        return null;
6809    }
6810
6811    @Override
6812    public void setProcessLimit(int max) {
6813        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6814                "setProcessLimit()");
6815        synchronized (this) {
6816            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6817            mProcessLimitOverride = max;
6818        }
6819        trimApplications();
6820    }
6821
6822    @Override
6823    public int getProcessLimit() {
6824        synchronized (this) {
6825            return mProcessLimitOverride;
6826        }
6827    }
6828
6829    void foregroundTokenDied(ForegroundToken token) {
6830        synchronized (ActivityManagerService.this) {
6831            synchronized (mPidsSelfLocked) {
6832                ForegroundToken cur
6833                    = mForegroundProcesses.get(token.pid);
6834                if (cur != token) {
6835                    return;
6836                }
6837                mForegroundProcesses.remove(token.pid);
6838                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6839                if (pr == null) {
6840                    return;
6841                }
6842                pr.forcingToForeground = null;
6843                updateProcessForegroundLocked(pr, false, false);
6844            }
6845            updateOomAdjLocked();
6846        }
6847    }
6848
6849    @Override
6850    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6851        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6852                "setProcessForeground()");
6853        synchronized(this) {
6854            boolean changed = false;
6855
6856            synchronized (mPidsSelfLocked) {
6857                ProcessRecord pr = mPidsSelfLocked.get(pid);
6858                if (pr == null && isForeground) {
6859                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6860                    return;
6861                }
6862                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6863                if (oldToken != null) {
6864                    oldToken.token.unlinkToDeath(oldToken, 0);
6865                    mForegroundProcesses.remove(pid);
6866                    if (pr != null) {
6867                        pr.forcingToForeground = null;
6868                    }
6869                    changed = true;
6870                }
6871                if (isForeground && token != null) {
6872                    ForegroundToken newToken = new ForegroundToken() {
6873                        @Override
6874                        public void binderDied() {
6875                            foregroundTokenDied(this);
6876                        }
6877                    };
6878                    newToken.pid = pid;
6879                    newToken.token = token;
6880                    try {
6881                        token.linkToDeath(newToken, 0);
6882                        mForegroundProcesses.put(pid, newToken);
6883                        pr.forcingToForeground = token;
6884                        changed = true;
6885                    } catch (RemoteException e) {
6886                        // If the process died while doing this, we will later
6887                        // do the cleanup with the process death link.
6888                    }
6889                }
6890            }
6891
6892            if (changed) {
6893                updateOomAdjLocked();
6894            }
6895        }
6896    }
6897
6898    // =========================================================
6899    // PERMISSIONS
6900    // =========================================================
6901
6902    static class PermissionController extends IPermissionController.Stub {
6903        ActivityManagerService mActivityManagerService;
6904        PermissionController(ActivityManagerService activityManagerService) {
6905            mActivityManagerService = activityManagerService;
6906        }
6907
6908        @Override
6909        public boolean checkPermission(String permission, int pid, int uid) {
6910            return mActivityManagerService.checkPermission(permission, pid,
6911                    uid) == PackageManager.PERMISSION_GRANTED;
6912        }
6913    }
6914
6915    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6916        @Override
6917        public int checkComponentPermission(String permission, int pid, int uid,
6918                int owningUid, boolean exported) {
6919            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6920                    owningUid, exported);
6921        }
6922
6923        @Override
6924        public Object getAMSLock() {
6925            return ActivityManagerService.this;
6926        }
6927    }
6928
6929    /**
6930     * This can be called with or without the global lock held.
6931     */
6932    int checkComponentPermission(String permission, int pid, int uid,
6933            int owningUid, boolean exported) {
6934        // We might be performing an operation on behalf of an indirect binder
6935        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6936        // client identity accordingly before proceeding.
6937        Identity tlsIdentity = sCallerIdentity.get();
6938        if (tlsIdentity != null) {
6939            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6940                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6941            uid = tlsIdentity.uid;
6942            pid = tlsIdentity.pid;
6943        }
6944
6945        if (pid == MY_PID) {
6946            return PackageManager.PERMISSION_GRANTED;
6947        }
6948
6949        return ActivityManager.checkComponentPermission(permission, uid,
6950                owningUid, exported);
6951    }
6952
6953    /**
6954     * As the only public entry point for permissions checking, this method
6955     * can enforce the semantic that requesting a check on a null global
6956     * permission is automatically denied.  (Internally a null permission
6957     * string is used when calling {@link #checkComponentPermission} in cases
6958     * when only uid-based security is needed.)
6959     *
6960     * This can be called with or without the global lock held.
6961     */
6962    @Override
6963    public int checkPermission(String permission, int pid, int uid) {
6964        if (permission == null) {
6965            return PackageManager.PERMISSION_DENIED;
6966        }
6967        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6968    }
6969
6970    /**
6971     * Binder IPC calls go through the public entry point.
6972     * This can be called with or without the global lock held.
6973     */
6974    int checkCallingPermission(String permission) {
6975        return checkPermission(permission,
6976                Binder.getCallingPid(),
6977                UserHandle.getAppId(Binder.getCallingUid()));
6978    }
6979
6980    /**
6981     * This can be called with or without the global lock held.
6982     */
6983    void enforceCallingPermission(String permission, String func) {
6984        if (checkCallingPermission(permission)
6985                == PackageManager.PERMISSION_GRANTED) {
6986            return;
6987        }
6988
6989        String msg = "Permission Denial: " + func + " from pid="
6990                + Binder.getCallingPid()
6991                + ", uid=" + Binder.getCallingUid()
6992                + " requires " + permission;
6993        Slog.w(TAG, msg);
6994        throw new SecurityException(msg);
6995    }
6996
6997    /**
6998     * Determine if UID is holding permissions required to access {@link Uri} in
6999     * the given {@link ProviderInfo}. Final permission checking is always done
7000     * in {@link ContentProvider}.
7001     */
7002    private final boolean checkHoldingPermissionsLocked(
7003            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7004        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7005                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7006        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7007            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7008                    != PERMISSION_GRANTED) {
7009                return false;
7010            }
7011        }
7012        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7013    }
7014
7015    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7016            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7017        if (pi.applicationInfo.uid == uid) {
7018            return true;
7019        } else if (!pi.exported) {
7020            return false;
7021        }
7022
7023        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7024        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7025        try {
7026            // check if target holds top-level <provider> permissions
7027            if (!readMet && pi.readPermission != null && considerUidPermissions
7028                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7029                readMet = true;
7030            }
7031            if (!writeMet && pi.writePermission != null && considerUidPermissions
7032                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7033                writeMet = true;
7034            }
7035
7036            // track if unprotected read/write is allowed; any denied
7037            // <path-permission> below removes this ability
7038            boolean allowDefaultRead = pi.readPermission == null;
7039            boolean allowDefaultWrite = pi.writePermission == null;
7040
7041            // check if target holds any <path-permission> that match uri
7042            final PathPermission[] pps = pi.pathPermissions;
7043            if (pps != null) {
7044                final String path = grantUri.uri.getPath();
7045                int i = pps.length;
7046                while (i > 0 && (!readMet || !writeMet)) {
7047                    i--;
7048                    PathPermission pp = pps[i];
7049                    if (pp.match(path)) {
7050                        if (!readMet) {
7051                            final String pprperm = pp.getReadPermission();
7052                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7053                                    + pprperm + " for " + pp.getPath()
7054                                    + ": match=" + pp.match(path)
7055                                    + " check=" + pm.checkUidPermission(pprperm, uid));
7056                            if (pprperm != null) {
7057                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7058                                        == PERMISSION_GRANTED) {
7059                                    readMet = true;
7060                                } else {
7061                                    allowDefaultRead = false;
7062                                }
7063                            }
7064                        }
7065                        if (!writeMet) {
7066                            final String ppwperm = pp.getWritePermission();
7067                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7068                                    + ppwperm + " for " + pp.getPath()
7069                                    + ": match=" + pp.match(path)
7070                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
7071                            if (ppwperm != null) {
7072                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7073                                        == PERMISSION_GRANTED) {
7074                                    writeMet = true;
7075                                } else {
7076                                    allowDefaultWrite = false;
7077                                }
7078                            }
7079                        }
7080                    }
7081                }
7082            }
7083
7084            // grant unprotected <provider> read/write, if not blocked by
7085            // <path-permission> above
7086            if (allowDefaultRead) readMet = true;
7087            if (allowDefaultWrite) writeMet = true;
7088
7089        } catch (RemoteException e) {
7090            return false;
7091        }
7092
7093        return readMet && writeMet;
7094    }
7095
7096    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7097        ProviderInfo pi = null;
7098        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7099        if (cpr != null) {
7100            pi = cpr.info;
7101        } else {
7102            try {
7103                pi = AppGlobals.getPackageManager().resolveContentProvider(
7104                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7105            } catch (RemoteException ex) {
7106            }
7107        }
7108        return pi;
7109    }
7110
7111    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7112        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7113        if (targetUris != null) {
7114            return targetUris.get(grantUri);
7115        }
7116        return null;
7117    }
7118
7119    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7120            String targetPkg, int targetUid, GrantUri grantUri) {
7121        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7122        if (targetUris == null) {
7123            targetUris = Maps.newArrayMap();
7124            mGrantedUriPermissions.put(targetUid, targetUris);
7125        }
7126
7127        UriPermission perm = targetUris.get(grantUri);
7128        if (perm == null) {
7129            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7130            targetUris.put(grantUri, perm);
7131        }
7132
7133        return perm;
7134    }
7135
7136    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7137            final int modeFlags) {
7138        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7139        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7140                : UriPermission.STRENGTH_OWNED;
7141
7142        // Root gets to do everything.
7143        if (uid == 0) {
7144            return true;
7145        }
7146
7147        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7148        if (perms == null) return false;
7149
7150        // First look for exact match
7151        final UriPermission exactPerm = perms.get(grantUri);
7152        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7153            return true;
7154        }
7155
7156        // No exact match, look for prefixes
7157        final int N = perms.size();
7158        for (int i = 0; i < N; i++) {
7159            final UriPermission perm = perms.valueAt(i);
7160            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7161                    && perm.getStrength(modeFlags) >= minStrength) {
7162                return true;
7163            }
7164        }
7165
7166        return false;
7167    }
7168
7169    /**
7170     * @param uri This uri must NOT contain an embedded userId.
7171     * @param userId The userId in which the uri is to be resolved.
7172     */
7173    @Override
7174    public int checkUriPermission(Uri uri, int pid, int uid,
7175            final int modeFlags, int userId) {
7176        enforceNotIsolatedCaller("checkUriPermission");
7177
7178        // Another redirected-binder-call permissions check as in
7179        // {@link checkComponentPermission}.
7180        Identity tlsIdentity = sCallerIdentity.get();
7181        if (tlsIdentity != null) {
7182            uid = tlsIdentity.uid;
7183            pid = tlsIdentity.pid;
7184        }
7185
7186        // Our own process gets to do everything.
7187        if (pid == MY_PID) {
7188            return PackageManager.PERMISSION_GRANTED;
7189        }
7190        synchronized (this) {
7191            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7192                    ? PackageManager.PERMISSION_GRANTED
7193                    : PackageManager.PERMISSION_DENIED;
7194        }
7195    }
7196
7197    /**
7198     * Check if the targetPkg can be granted permission to access uri by
7199     * the callingUid using the given modeFlags.  Throws a security exception
7200     * if callingUid is not allowed to do this.  Returns the uid of the target
7201     * if the URI permission grant should be performed; returns -1 if it is not
7202     * needed (for example targetPkg already has permission to access the URI).
7203     * If you already know the uid of the target, you can supply it in
7204     * lastTargetUid else set that to -1.
7205     */
7206    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7207            final int modeFlags, int lastTargetUid) {
7208        if (!Intent.isAccessUriMode(modeFlags)) {
7209            return -1;
7210        }
7211
7212        if (targetPkg != null) {
7213            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7214                    "Checking grant " + targetPkg + " permission to " + grantUri);
7215        }
7216
7217        final IPackageManager pm = AppGlobals.getPackageManager();
7218
7219        // If this is not a content: uri, we can't do anything with it.
7220        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7221            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7222                    "Can't grant URI permission for non-content URI: " + grantUri);
7223            return -1;
7224        }
7225
7226        final String authority = grantUri.uri.getAuthority();
7227        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7228        if (pi == null) {
7229            Slog.w(TAG, "No content provider found for permission check: " +
7230                    grantUri.uri.toSafeString());
7231            return -1;
7232        }
7233
7234        int targetUid = lastTargetUid;
7235        if (targetUid < 0 && targetPkg != null) {
7236            try {
7237                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7238                if (targetUid < 0) {
7239                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7240                            "Can't grant URI permission no uid for: " + targetPkg);
7241                    return -1;
7242                }
7243            } catch (RemoteException ex) {
7244                return -1;
7245            }
7246        }
7247
7248        if (targetUid >= 0) {
7249            // First...  does the target actually need this permission?
7250            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7251                // No need to grant the target this permission.
7252                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7253                        "Target " + targetPkg + " already has full permission to " + grantUri);
7254                return -1;
7255            }
7256        } else {
7257            // First...  there is no target package, so can anyone access it?
7258            boolean allowed = pi.exported;
7259            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7260                if (pi.readPermission != null) {
7261                    allowed = false;
7262                }
7263            }
7264            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7265                if (pi.writePermission != null) {
7266                    allowed = false;
7267                }
7268            }
7269            if (allowed) {
7270                return -1;
7271            }
7272        }
7273
7274        /* There is a special cross user grant if:
7275         * - The target is on another user.
7276         * - Apps on the current user can access the uri without any uid permissions.
7277         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7278         * grant uri permissions.
7279         */
7280        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7281                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7282                modeFlags, false /*without considering the uid permissions*/);
7283
7284        // Second...  is the provider allowing granting of URI permissions?
7285        if (!specialCrossUserGrant) {
7286            if (!pi.grantUriPermissions) {
7287                throw new SecurityException("Provider " + pi.packageName
7288                        + "/" + pi.name
7289                        + " does not allow granting of Uri permissions (uri "
7290                        + grantUri + ")");
7291            }
7292            if (pi.uriPermissionPatterns != null) {
7293                final int N = pi.uriPermissionPatterns.length;
7294                boolean allowed = false;
7295                for (int i=0; i<N; i++) {
7296                    if (pi.uriPermissionPatterns[i] != null
7297                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7298                        allowed = true;
7299                        break;
7300                    }
7301                }
7302                if (!allowed) {
7303                    throw new SecurityException("Provider " + pi.packageName
7304                            + "/" + pi.name
7305                            + " does not allow granting of permission to path of Uri "
7306                            + grantUri);
7307                }
7308            }
7309        }
7310
7311        // Third...  does the caller itself have permission to access
7312        // this uri?
7313        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7314            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7315                // Require they hold a strong enough Uri permission
7316                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7317                    throw new SecurityException("Uid " + callingUid
7318                            + " does not have permission to uri " + grantUri);
7319                }
7320            }
7321        }
7322        return targetUid;
7323    }
7324
7325    /**
7326     * @param uri This uri must NOT contain an embedded userId.
7327     * @param userId The userId in which the uri is to be resolved.
7328     */
7329    @Override
7330    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7331            final int modeFlags, int userId) {
7332        enforceNotIsolatedCaller("checkGrantUriPermission");
7333        synchronized(this) {
7334            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7335                    new GrantUri(userId, uri, false), modeFlags, -1);
7336        }
7337    }
7338
7339    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7340            final int modeFlags, UriPermissionOwner owner) {
7341        if (!Intent.isAccessUriMode(modeFlags)) {
7342            return;
7343        }
7344
7345        // So here we are: the caller has the assumed permission
7346        // to the uri, and the target doesn't.  Let's now give this to
7347        // the target.
7348
7349        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7350                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7351
7352        final String authority = grantUri.uri.getAuthority();
7353        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7354        if (pi == null) {
7355            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7356            return;
7357        }
7358
7359        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7360            grantUri.prefix = true;
7361        }
7362        final UriPermission perm = findOrCreateUriPermissionLocked(
7363                pi.packageName, targetPkg, targetUid, grantUri);
7364        perm.grantModes(modeFlags, owner);
7365    }
7366
7367    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7368            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7369        if (targetPkg == null) {
7370            throw new NullPointerException("targetPkg");
7371        }
7372        int targetUid;
7373        final IPackageManager pm = AppGlobals.getPackageManager();
7374        try {
7375            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7376        } catch (RemoteException ex) {
7377            return;
7378        }
7379
7380        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7381                targetUid);
7382        if (targetUid < 0) {
7383            return;
7384        }
7385
7386        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7387                owner);
7388    }
7389
7390    static class NeededUriGrants extends ArrayList<GrantUri> {
7391        final String targetPkg;
7392        final int targetUid;
7393        final int flags;
7394
7395        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7396            this.targetPkg = targetPkg;
7397            this.targetUid = targetUid;
7398            this.flags = flags;
7399        }
7400    }
7401
7402    /**
7403     * Like checkGrantUriPermissionLocked, but takes an Intent.
7404     */
7405    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7406            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7407        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7408                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7409                + " clip=" + (intent != null ? intent.getClipData() : null)
7410                + " from " + intent + "; flags=0x"
7411                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7412
7413        if (targetPkg == null) {
7414            throw new NullPointerException("targetPkg");
7415        }
7416
7417        if (intent == null) {
7418            return null;
7419        }
7420        Uri data = intent.getData();
7421        ClipData clip = intent.getClipData();
7422        if (data == null && clip == null) {
7423            return null;
7424        }
7425        // Default userId for uris in the intent (if they don't specify it themselves)
7426        int contentUserHint = intent.getContentUserHint();
7427        if (contentUserHint == UserHandle.USER_CURRENT) {
7428            contentUserHint = UserHandle.getUserId(callingUid);
7429        }
7430        final IPackageManager pm = AppGlobals.getPackageManager();
7431        int targetUid;
7432        if (needed != null) {
7433            targetUid = needed.targetUid;
7434        } else {
7435            try {
7436                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7437            } catch (RemoteException ex) {
7438                return null;
7439            }
7440            if (targetUid < 0) {
7441                if (DEBUG_URI_PERMISSION) {
7442                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7443                            + " on user " + targetUserId);
7444                }
7445                return null;
7446            }
7447        }
7448        if (data != null) {
7449            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7450            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7451                    targetUid);
7452            if (targetUid > 0) {
7453                if (needed == null) {
7454                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7455                }
7456                needed.add(grantUri);
7457            }
7458        }
7459        if (clip != null) {
7460            for (int i=0; i<clip.getItemCount(); i++) {
7461                Uri uri = clip.getItemAt(i).getUri();
7462                if (uri != null) {
7463                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7464                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7465                            targetUid);
7466                    if (targetUid > 0) {
7467                        if (needed == null) {
7468                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7469                        }
7470                        needed.add(grantUri);
7471                    }
7472                } else {
7473                    Intent clipIntent = clip.getItemAt(i).getIntent();
7474                    if (clipIntent != null) {
7475                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7476                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7477                        if (newNeeded != null) {
7478                            needed = newNeeded;
7479                        }
7480                    }
7481                }
7482            }
7483        }
7484
7485        return needed;
7486    }
7487
7488    /**
7489     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7490     */
7491    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7492            UriPermissionOwner owner) {
7493        if (needed != null) {
7494            for (int i=0; i<needed.size(); i++) {
7495                GrantUri grantUri = needed.get(i);
7496                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7497                        grantUri, needed.flags, owner);
7498            }
7499        }
7500    }
7501
7502    void grantUriPermissionFromIntentLocked(int callingUid,
7503            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7504        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7505                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7506        if (needed == null) {
7507            return;
7508        }
7509
7510        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7511    }
7512
7513    /**
7514     * @param uri This uri must NOT contain an embedded userId.
7515     * @param userId The userId in which the uri is to be resolved.
7516     */
7517    @Override
7518    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7519            final int modeFlags, int userId) {
7520        enforceNotIsolatedCaller("grantUriPermission");
7521        GrantUri grantUri = new GrantUri(userId, uri, false);
7522        synchronized(this) {
7523            final ProcessRecord r = getRecordForAppLocked(caller);
7524            if (r == null) {
7525                throw new SecurityException("Unable to find app for caller "
7526                        + caller
7527                        + " when granting permission to uri " + grantUri);
7528            }
7529            if (targetPkg == null) {
7530                throw new IllegalArgumentException("null target");
7531            }
7532            if (grantUri == null) {
7533                throw new IllegalArgumentException("null uri");
7534            }
7535
7536            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7537                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7538                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7539                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7540
7541            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7542                    UserHandle.getUserId(r.uid));
7543        }
7544    }
7545
7546    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7547        if (perm.modeFlags == 0) {
7548            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7549                    perm.targetUid);
7550            if (perms != null) {
7551                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7552                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7553
7554                perms.remove(perm.uri);
7555                if (perms.isEmpty()) {
7556                    mGrantedUriPermissions.remove(perm.targetUid);
7557                }
7558            }
7559        }
7560    }
7561
7562    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7563        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7564
7565        final IPackageManager pm = AppGlobals.getPackageManager();
7566        final String authority = grantUri.uri.getAuthority();
7567        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7568        if (pi == null) {
7569            Slog.w(TAG, "No content provider found for permission revoke: "
7570                    + grantUri.toSafeString());
7571            return;
7572        }
7573
7574        // Does the caller have this permission on the URI?
7575        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7576            // If they don't have direct access to the URI, then revoke any
7577            // ownerless URI permissions that have been granted to them.
7578            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7579            if (perms != null) {
7580                boolean persistChanged = false;
7581                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7582                    final UriPermission perm = it.next();
7583                    if (perm.uri.sourceUserId == grantUri.sourceUserId
7584                            && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7585                        if (DEBUG_URI_PERMISSION)
7586                            Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7587                                    " permission to " + perm.uri);
7588                        persistChanged |= perm.revokeModes(
7589                                modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7590                        if (perm.modeFlags == 0) {
7591                            it.remove();
7592                        }
7593                    }
7594                }
7595                if (perms.isEmpty()) {
7596                    mGrantedUriPermissions.remove(callingUid);
7597                }
7598                if (persistChanged) {
7599                    schedulePersistUriGrants();
7600                }
7601            }
7602            return;
7603        }
7604
7605        boolean persistChanged = false;
7606
7607        // Go through all of the permissions and remove any that match.
7608        int N = mGrantedUriPermissions.size();
7609        for (int i = 0; i < N; i++) {
7610            final int targetUid = mGrantedUriPermissions.keyAt(i);
7611            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7612
7613            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7614                final UriPermission perm = it.next();
7615                if (perm.uri.sourceUserId == grantUri.sourceUserId
7616                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7617                    if (DEBUG_URI_PERMISSION)
7618                        Slog.v(TAG,
7619                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7620                    persistChanged |= perm.revokeModes(
7621                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7622                    if (perm.modeFlags == 0) {
7623                        it.remove();
7624                    }
7625                }
7626            }
7627
7628            if (perms.isEmpty()) {
7629                mGrantedUriPermissions.remove(targetUid);
7630                N--;
7631                i--;
7632            }
7633        }
7634
7635        if (persistChanged) {
7636            schedulePersistUriGrants();
7637        }
7638    }
7639
7640    /**
7641     * @param uri This uri must NOT contain an embedded userId.
7642     * @param userId The userId in which the uri is to be resolved.
7643     */
7644    @Override
7645    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7646            int userId) {
7647        enforceNotIsolatedCaller("revokeUriPermission");
7648        synchronized(this) {
7649            final ProcessRecord r = getRecordForAppLocked(caller);
7650            if (r == null) {
7651                throw new SecurityException("Unable to find app for caller "
7652                        + caller
7653                        + " when revoking permission to uri " + uri);
7654            }
7655            if (uri == null) {
7656                Slog.w(TAG, "revokeUriPermission: null uri");
7657                return;
7658            }
7659
7660            if (!Intent.isAccessUriMode(modeFlags)) {
7661                return;
7662            }
7663
7664            final IPackageManager pm = AppGlobals.getPackageManager();
7665            final String authority = uri.getAuthority();
7666            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7667            if (pi == null) {
7668                Slog.w(TAG, "No content provider found for permission revoke: "
7669                        + uri.toSafeString());
7670                return;
7671            }
7672
7673            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7674        }
7675    }
7676
7677    /**
7678     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7679     * given package.
7680     *
7681     * @param packageName Package name to match, or {@code null} to apply to all
7682     *            packages.
7683     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7684     *            to all users.
7685     * @param persistable If persistable grants should be removed.
7686     */
7687    private void removeUriPermissionsForPackageLocked(
7688            String packageName, int userHandle, boolean persistable) {
7689        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7690            throw new IllegalArgumentException("Must narrow by either package or user");
7691        }
7692
7693        boolean persistChanged = false;
7694
7695        int N = mGrantedUriPermissions.size();
7696        for (int i = 0; i < N; i++) {
7697            final int targetUid = mGrantedUriPermissions.keyAt(i);
7698            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7699
7700            // Only inspect grants matching user
7701            if (userHandle == UserHandle.USER_ALL
7702                    || userHandle == UserHandle.getUserId(targetUid)) {
7703                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7704                    final UriPermission perm = it.next();
7705
7706                    // Only inspect grants matching package
7707                    if (packageName == null || perm.sourcePkg.equals(packageName)
7708                            || perm.targetPkg.equals(packageName)) {
7709                        persistChanged |= perm.revokeModes(persistable
7710                                ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7711
7712                        // Only remove when no modes remain; any persisted grants
7713                        // will keep this alive.
7714                        if (perm.modeFlags == 0) {
7715                            it.remove();
7716                        }
7717                    }
7718                }
7719
7720                if (perms.isEmpty()) {
7721                    mGrantedUriPermissions.remove(targetUid);
7722                    N--;
7723                    i--;
7724                }
7725            }
7726        }
7727
7728        if (persistChanged) {
7729            schedulePersistUriGrants();
7730        }
7731    }
7732
7733    @Override
7734    public IBinder newUriPermissionOwner(String name) {
7735        enforceNotIsolatedCaller("newUriPermissionOwner");
7736        synchronized(this) {
7737            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7738            return owner.getExternalTokenLocked();
7739        }
7740    }
7741
7742    /**
7743     * @param uri This uri must NOT contain an embedded userId.
7744     * @param sourceUserId The userId in which the uri is to be resolved.
7745     * @param targetUserId The userId of the app that receives the grant.
7746     */
7747    @Override
7748    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7749            final int modeFlags, int sourceUserId, int targetUserId) {
7750        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7751                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7752        synchronized(this) {
7753            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7754            if (owner == null) {
7755                throw new IllegalArgumentException("Unknown owner: " + token);
7756            }
7757            if (fromUid != Binder.getCallingUid()) {
7758                if (Binder.getCallingUid() != Process.myUid()) {
7759                    // Only system code can grant URI permissions on behalf
7760                    // of other users.
7761                    throw new SecurityException("nice try");
7762                }
7763            }
7764            if (targetPkg == null) {
7765                throw new IllegalArgumentException("null target");
7766            }
7767            if (uri == null) {
7768                throw new IllegalArgumentException("null uri");
7769            }
7770
7771            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7772                    modeFlags, owner, targetUserId);
7773        }
7774    }
7775
7776    /**
7777     * @param uri This uri must NOT contain an embedded userId.
7778     * @param userId The userId in which the uri is to be resolved.
7779     */
7780    @Override
7781    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7782        synchronized(this) {
7783            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7784            if (owner == null) {
7785                throw new IllegalArgumentException("Unknown owner: " + token);
7786            }
7787
7788            if (uri == null) {
7789                owner.removeUriPermissionsLocked(mode);
7790            } else {
7791                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7792            }
7793        }
7794    }
7795
7796    private void schedulePersistUriGrants() {
7797        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7798            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7799                    10 * DateUtils.SECOND_IN_MILLIS);
7800        }
7801    }
7802
7803    private void writeGrantedUriPermissions() {
7804        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7805
7806        // Snapshot permissions so we can persist without lock
7807        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7808        synchronized (this) {
7809            final int size = mGrantedUriPermissions.size();
7810            for (int i = 0; i < size; i++) {
7811                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7812                for (UriPermission perm : perms.values()) {
7813                    if (perm.persistedModeFlags != 0) {
7814                        persist.add(perm.snapshot());
7815                    }
7816                }
7817            }
7818        }
7819
7820        FileOutputStream fos = null;
7821        try {
7822            fos = mGrantFile.startWrite();
7823
7824            XmlSerializer out = new FastXmlSerializer();
7825            out.setOutput(fos, "utf-8");
7826            out.startDocument(null, true);
7827            out.startTag(null, TAG_URI_GRANTS);
7828            for (UriPermission.Snapshot perm : persist) {
7829                out.startTag(null, TAG_URI_GRANT);
7830                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7831                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7832                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7833                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7834                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7835                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7836                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7837                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7838                out.endTag(null, TAG_URI_GRANT);
7839            }
7840            out.endTag(null, TAG_URI_GRANTS);
7841            out.endDocument();
7842
7843            mGrantFile.finishWrite(fos);
7844        } catch (IOException e) {
7845            if (fos != null) {
7846                mGrantFile.failWrite(fos);
7847            }
7848        }
7849    }
7850
7851    private void readGrantedUriPermissionsLocked() {
7852        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7853
7854        final long now = System.currentTimeMillis();
7855
7856        FileInputStream fis = null;
7857        try {
7858            fis = mGrantFile.openRead();
7859            final XmlPullParser in = Xml.newPullParser();
7860            in.setInput(fis, null);
7861
7862            int type;
7863            while ((type = in.next()) != END_DOCUMENT) {
7864                final String tag = in.getName();
7865                if (type == START_TAG) {
7866                    if (TAG_URI_GRANT.equals(tag)) {
7867                        final int sourceUserId;
7868                        final int targetUserId;
7869                        final int userHandle = readIntAttribute(in,
7870                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7871                        if (userHandle != UserHandle.USER_NULL) {
7872                            // For backwards compatibility.
7873                            sourceUserId = userHandle;
7874                            targetUserId = userHandle;
7875                        } else {
7876                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7877                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7878                        }
7879                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7880                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7881                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7882                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7883                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7884                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7885
7886                        // Sanity check that provider still belongs to source package
7887                        final ProviderInfo pi = getProviderInfoLocked(
7888                                uri.getAuthority(), sourceUserId);
7889                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7890                            int targetUid = -1;
7891                            try {
7892                                targetUid = AppGlobals.getPackageManager()
7893                                        .getPackageUid(targetPkg, targetUserId);
7894                            } catch (RemoteException e) {
7895                            }
7896                            if (targetUid != -1) {
7897                                final UriPermission perm = findOrCreateUriPermissionLocked(
7898                                        sourcePkg, targetPkg, targetUid,
7899                                        new GrantUri(sourceUserId, uri, prefix));
7900                                perm.initPersistedModes(modeFlags, createdTime);
7901                            }
7902                        } else {
7903                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7904                                    + " but instead found " + pi);
7905                        }
7906                    }
7907                }
7908            }
7909        } catch (FileNotFoundException e) {
7910            // Missing grants is okay
7911        } catch (IOException e) {
7912            Log.wtf(TAG, "Failed reading Uri grants", e);
7913        } catch (XmlPullParserException e) {
7914            Log.wtf(TAG, "Failed reading Uri grants", e);
7915        } finally {
7916            IoUtils.closeQuietly(fis);
7917        }
7918    }
7919
7920    /**
7921     * @param uri This uri must NOT contain an embedded userId.
7922     * @param userId The userId in which the uri is to be resolved.
7923     */
7924    @Override
7925    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7926        enforceNotIsolatedCaller("takePersistableUriPermission");
7927
7928        Preconditions.checkFlagsArgument(modeFlags,
7929                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7930
7931        synchronized (this) {
7932            final int callingUid = Binder.getCallingUid();
7933            boolean persistChanged = false;
7934            GrantUri grantUri = new GrantUri(userId, uri, false);
7935
7936            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7937                    new GrantUri(userId, uri, false));
7938            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7939                    new GrantUri(userId, uri, true));
7940
7941            final boolean exactValid = (exactPerm != null)
7942                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7943            final boolean prefixValid = (prefixPerm != null)
7944                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7945
7946            if (!(exactValid || prefixValid)) {
7947                throw new SecurityException("No persistable permission grants found for UID "
7948                        + callingUid + " and Uri " + grantUri.toSafeString());
7949            }
7950
7951            if (exactValid) {
7952                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7953            }
7954            if (prefixValid) {
7955                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7956            }
7957
7958            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7959
7960            if (persistChanged) {
7961                schedulePersistUriGrants();
7962            }
7963        }
7964    }
7965
7966    /**
7967     * @param uri This uri must NOT contain an embedded userId.
7968     * @param userId The userId in which the uri is to be resolved.
7969     */
7970    @Override
7971    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7972        enforceNotIsolatedCaller("releasePersistableUriPermission");
7973
7974        Preconditions.checkFlagsArgument(modeFlags,
7975                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7976
7977        synchronized (this) {
7978            final int callingUid = Binder.getCallingUid();
7979            boolean persistChanged = false;
7980
7981            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7982                    new GrantUri(userId, uri, false));
7983            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7984                    new GrantUri(userId, uri, true));
7985            if (exactPerm == null && prefixPerm == null) {
7986                throw new SecurityException("No permission grants found for UID " + callingUid
7987                        + " and Uri " + uri.toSafeString());
7988            }
7989
7990            if (exactPerm != null) {
7991                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7992                removeUriPermissionIfNeededLocked(exactPerm);
7993            }
7994            if (prefixPerm != null) {
7995                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7996                removeUriPermissionIfNeededLocked(prefixPerm);
7997            }
7998
7999            if (persistChanged) {
8000                schedulePersistUriGrants();
8001            }
8002        }
8003    }
8004
8005    /**
8006     * Prune any older {@link UriPermission} for the given UID until outstanding
8007     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8008     *
8009     * @return if any mutations occured that require persisting.
8010     */
8011    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8012        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8013        if (perms == null) return false;
8014        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8015
8016        final ArrayList<UriPermission> persisted = Lists.newArrayList();
8017        for (UriPermission perm : perms.values()) {
8018            if (perm.persistedModeFlags != 0) {
8019                persisted.add(perm);
8020            }
8021        }
8022
8023        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8024        if (trimCount <= 0) return false;
8025
8026        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8027        for (int i = 0; i < trimCount; i++) {
8028            final UriPermission perm = persisted.get(i);
8029
8030            if (DEBUG_URI_PERMISSION) {
8031                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8032            }
8033
8034            perm.releasePersistableModes(~0);
8035            removeUriPermissionIfNeededLocked(perm);
8036        }
8037
8038        return true;
8039    }
8040
8041    @Override
8042    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8043            String packageName, boolean incoming) {
8044        enforceNotIsolatedCaller("getPersistedUriPermissions");
8045        Preconditions.checkNotNull(packageName, "packageName");
8046
8047        final int callingUid = Binder.getCallingUid();
8048        final IPackageManager pm = AppGlobals.getPackageManager();
8049        try {
8050            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8051            if (packageUid != callingUid) {
8052                throw new SecurityException(
8053                        "Package " + packageName + " does not belong to calling UID " + callingUid);
8054            }
8055        } catch (RemoteException e) {
8056            throw new SecurityException("Failed to verify package name ownership");
8057        }
8058
8059        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8060        synchronized (this) {
8061            if (incoming) {
8062                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8063                        callingUid);
8064                if (perms == null) {
8065                    Slog.w(TAG, "No permission grants found for " + packageName);
8066                } else {
8067                    for (UriPermission perm : perms.values()) {
8068                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8069                            result.add(perm.buildPersistedPublicApiObject());
8070                        }
8071                    }
8072                }
8073            } else {
8074                final int size = mGrantedUriPermissions.size();
8075                for (int i = 0; i < size; i++) {
8076                    final ArrayMap<GrantUri, UriPermission> perms =
8077                            mGrantedUriPermissions.valueAt(i);
8078                    for (UriPermission perm : perms.values()) {
8079                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8080                            result.add(perm.buildPersistedPublicApiObject());
8081                        }
8082                    }
8083                }
8084            }
8085        }
8086        return new ParceledListSlice<android.content.UriPermission>(result);
8087    }
8088
8089    @Override
8090    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8091        synchronized (this) {
8092            ProcessRecord app =
8093                who != null ? getRecordForAppLocked(who) : null;
8094            if (app == null) return;
8095
8096            Message msg = Message.obtain();
8097            msg.what = WAIT_FOR_DEBUGGER_MSG;
8098            msg.obj = app;
8099            msg.arg1 = waiting ? 1 : 0;
8100            mHandler.sendMessage(msg);
8101        }
8102    }
8103
8104    @Override
8105    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8106        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8107        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8108        outInfo.availMem = Process.getFreeMemory();
8109        outInfo.totalMem = Process.getTotalMemory();
8110        outInfo.threshold = homeAppMem;
8111        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8112        outInfo.hiddenAppThreshold = cachedAppMem;
8113        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8114                ProcessList.SERVICE_ADJ);
8115        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8116                ProcessList.VISIBLE_APP_ADJ);
8117        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8118                ProcessList.FOREGROUND_APP_ADJ);
8119    }
8120
8121    // =========================================================
8122    // TASK MANAGEMENT
8123    // =========================================================
8124
8125    @Override
8126    public List<IAppTask> getAppTasks(String callingPackage) {
8127        int callingUid = Binder.getCallingUid();
8128        long ident = Binder.clearCallingIdentity();
8129
8130        synchronized(this) {
8131            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8132            try {
8133                if (localLOGV) Slog.v(TAG, "getAppTasks");
8134
8135                final int N = mRecentTasks.size();
8136                for (int i = 0; i < N; i++) {
8137                    TaskRecord tr = mRecentTasks.get(i);
8138                    // Skip tasks that do not match the caller.  We don't need to verify
8139                    // callingPackage, because we are also limiting to callingUid and know
8140                    // that will limit to the correct security sandbox.
8141                    if (tr.effectiveUid != callingUid) {
8142                        continue;
8143                    }
8144                    Intent intent = tr.getBaseIntent();
8145                    if (intent == null ||
8146                            !callingPackage.equals(intent.getComponent().getPackageName())) {
8147                        continue;
8148                    }
8149                    ActivityManager.RecentTaskInfo taskInfo =
8150                            createRecentTaskInfoFromTaskRecord(tr);
8151                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8152                    list.add(taskImpl);
8153                }
8154            } finally {
8155                Binder.restoreCallingIdentity(ident);
8156            }
8157            return list;
8158        }
8159    }
8160
8161    @Override
8162    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8163        final int callingUid = Binder.getCallingUid();
8164        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8165
8166        synchronized(this) {
8167            if (localLOGV) Slog.v(
8168                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8169
8170            final boolean allowed = checkCallingPermission(
8171                    android.Manifest.permission.GET_TASKS)
8172                    == PackageManager.PERMISSION_GRANTED;
8173            if (!allowed) {
8174                Slog.w(TAG, "getTasks: caller " + callingUid
8175                        + " does not hold GET_TASKS; limiting output");
8176            }
8177
8178            // TODO: Improve with MRU list from all ActivityStacks.
8179            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8180        }
8181
8182        return list;
8183    }
8184
8185    TaskRecord getMostRecentTask() {
8186        return mRecentTasks.get(0);
8187    }
8188
8189    /**
8190     * Creates a new RecentTaskInfo from a TaskRecord.
8191     */
8192    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8193        // Update the task description to reflect any changes in the task stack
8194        tr.updateTaskDescription();
8195
8196        // Compose the recent task info
8197        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8198        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8199        rti.persistentId = tr.taskId;
8200        rti.baseIntent = new Intent(tr.getBaseIntent());
8201        rti.origActivity = tr.origActivity;
8202        rti.description = tr.lastDescription;
8203        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8204        rti.userId = tr.userId;
8205        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8206        rti.firstActiveTime = tr.firstActiveTime;
8207        rti.lastActiveTime = tr.lastActiveTime;
8208        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8209        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8210        return rti;
8211    }
8212
8213    @Override
8214    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8215        final int callingUid = Binder.getCallingUid();
8216        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8217                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8218
8219        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8220        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8221        synchronized (this) {
8222            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8223                    == PackageManager.PERMISSION_GRANTED;
8224            if (!allowed) {
8225                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8226                        + " does not hold GET_TASKS; limiting output");
8227            }
8228            final boolean detailed = checkCallingPermission(
8229                    android.Manifest.permission.GET_DETAILED_TASKS)
8230                    == PackageManager.PERMISSION_GRANTED;
8231
8232            final int N = mRecentTasks.size();
8233            ArrayList<ActivityManager.RecentTaskInfo> res
8234                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8235                            maxNum < N ? maxNum : N);
8236
8237            final Set<Integer> includedUsers;
8238            if (includeProfiles) {
8239                includedUsers = getProfileIdsLocked(userId);
8240            } else {
8241                includedUsers = new HashSet<Integer>();
8242            }
8243            includedUsers.add(Integer.valueOf(userId));
8244
8245            for (int i=0; i<N && maxNum > 0; i++) {
8246                TaskRecord tr = mRecentTasks.get(i);
8247                // Only add calling user or related users recent tasks
8248                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8249                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8250                    continue;
8251                }
8252
8253                // Return the entry if desired by the caller.  We always return
8254                // the first entry, because callers always expect this to be the
8255                // foreground app.  We may filter others if the caller has
8256                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8257                // we should exclude the entry.
8258
8259                if (i == 0
8260                        || withExcluded
8261                        || (tr.intent == null)
8262                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8263                                == 0)) {
8264                    if (!allowed) {
8265                        // If the caller doesn't have the GET_TASKS permission, then only
8266                        // allow them to see a small subset of tasks -- their own and home.
8267                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8268                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8269                            continue;
8270                        }
8271                    }
8272                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8273                        if (tr.stack != null && tr.stack.isHomeStack()) {
8274                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8275                            continue;
8276                        }
8277                    }
8278                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8279                        // Don't include auto remove tasks that are finished or finishing.
8280                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8281                                + tr);
8282                        continue;
8283                    }
8284                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8285                            && !tr.isAvailable) {
8286                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8287                        continue;
8288                    }
8289
8290                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8291                    if (!detailed) {
8292                        rti.baseIntent.replaceExtras((Bundle)null);
8293                    }
8294
8295                    res.add(rti);
8296                    maxNum--;
8297                }
8298            }
8299            return res;
8300        }
8301    }
8302
8303    private TaskRecord recentTaskForIdLocked(int id) {
8304        final int N = mRecentTasks.size();
8305            for (int i=0; i<N; i++) {
8306                TaskRecord tr = mRecentTasks.get(i);
8307                if (tr.taskId == id) {
8308                    return tr;
8309                }
8310            }
8311            return null;
8312    }
8313
8314    @Override
8315    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8316        synchronized (this) {
8317            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8318                    "getTaskThumbnail()");
8319            TaskRecord tr = recentTaskForIdLocked(id);
8320            if (tr != null) {
8321                return tr.getTaskThumbnailLocked();
8322            }
8323        }
8324        return null;
8325    }
8326
8327    @Override
8328    public int addAppTask(IBinder activityToken, Intent intent,
8329            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8330        final int callingUid = Binder.getCallingUid();
8331        final long callingIdent = Binder.clearCallingIdentity();
8332
8333        try {
8334            synchronized (this) {
8335                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8336                if (r == null) {
8337                    throw new IllegalArgumentException("Activity does not exist; token="
8338                            + activityToken);
8339                }
8340                ComponentName comp = intent.getComponent();
8341                if (comp == null) {
8342                    throw new IllegalArgumentException("Intent " + intent
8343                            + " must specify explicit component");
8344                }
8345                if (thumbnail.getWidth() != mThumbnailWidth
8346                        || thumbnail.getHeight() != mThumbnailHeight) {
8347                    throw new IllegalArgumentException("Bad thumbnail size: got "
8348                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8349                            + mThumbnailWidth + "x" + mThumbnailHeight);
8350                }
8351                if (intent.getSelector() != null) {
8352                    intent.setSelector(null);
8353                }
8354                if (intent.getSourceBounds() != null) {
8355                    intent.setSourceBounds(null);
8356                }
8357                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8358                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8359                        // The caller has added this as an auto-remove task...  that makes no
8360                        // sense, so turn off auto-remove.
8361                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8362                    }
8363                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8364                    // Must be a new task.
8365                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8366                }
8367                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8368                    mLastAddedTaskActivity = null;
8369                }
8370                ActivityInfo ainfo = mLastAddedTaskActivity;
8371                if (ainfo == null) {
8372                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8373                            comp, 0, UserHandle.getUserId(callingUid));
8374                    if (ainfo.applicationInfo.uid != callingUid) {
8375                        throw new SecurityException(
8376                                "Can't add task for another application: target uid="
8377                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8378                    }
8379                }
8380
8381                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8382                        intent, description);
8383
8384                int trimIdx = trimRecentsForTask(task, false);
8385                if (trimIdx >= 0) {
8386                    // If this would have caused a trim, then we'll abort because that
8387                    // means it would be added at the end of the list but then just removed.
8388                    return -1;
8389                }
8390
8391                final int N = mRecentTasks.size();
8392                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8393                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8394                    tr.removedFromRecents(mTaskPersister);
8395                }
8396
8397                task.inRecents = true;
8398                mRecentTasks.add(task);
8399                r.task.stack.addTask(task, false, false);
8400
8401                task.setLastThumbnail(thumbnail);
8402                task.freeLastThumbnail();
8403
8404                return task.taskId;
8405            }
8406        } finally {
8407            Binder.restoreCallingIdentity(callingIdent);
8408        }
8409    }
8410
8411    @Override
8412    public Point getAppTaskThumbnailSize() {
8413        synchronized (this) {
8414            return new Point(mThumbnailWidth,  mThumbnailHeight);
8415        }
8416    }
8417
8418    @Override
8419    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8420        synchronized (this) {
8421            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8422            if (r != null) {
8423                r.setTaskDescription(td);
8424                r.task.updateTaskDescription();
8425            }
8426        }
8427    }
8428
8429    @Override
8430    public Bitmap getTaskDescriptionIcon(String filename) {
8431        if (!FileUtils.isValidExtFilename(filename)
8432                || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8433            throw new IllegalArgumentException("Bad filename: " + filename);
8434        }
8435        return mTaskPersister.getTaskDescriptionIcon(filename);
8436    }
8437
8438    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8439        mRecentTasks.remove(tr);
8440        tr.removedFromRecents(mTaskPersister);
8441        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8442        Intent baseIntent = new Intent(
8443                tr.intent != null ? tr.intent : tr.affinityIntent);
8444        ComponentName component = baseIntent.getComponent();
8445        if (component == null) {
8446            Slog.w(TAG, "Now component for base intent of task: " + tr);
8447            return;
8448        }
8449
8450        // Find any running services associated with this app.
8451        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8452
8453        if (killProcesses) {
8454            // Find any running processes associated with this app.
8455            final String pkg = component.getPackageName();
8456            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8457            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8458            for (int i=0; i<pmap.size(); i++) {
8459                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8460                for (int j=0; j<uids.size(); j++) {
8461                    ProcessRecord proc = uids.valueAt(j);
8462                    if (proc.userId != tr.userId) {
8463                        continue;
8464                    }
8465                    if (!proc.pkgList.containsKey(pkg)) {
8466                        continue;
8467                    }
8468                    procs.add(proc);
8469                }
8470            }
8471
8472            // Kill the running processes.
8473            for (int i=0; i<procs.size(); i++) {
8474                ProcessRecord pr = procs.get(i);
8475                if (pr == mHomeProcess) {
8476                    // Don't kill the home process along with tasks from the same package.
8477                    continue;
8478                }
8479                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8480                    pr.kill("remove task", true);
8481                } else {
8482                    pr.waitingToKill = "remove task";
8483                }
8484            }
8485        }
8486    }
8487
8488    /**
8489     * Removes the task with the specified task id.
8490     *
8491     * @param taskId Identifier of the task to be removed.
8492     * @param flags Additional operational flags.  May be 0 or
8493     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8494     * @return Returns true if the given task was found and removed.
8495     */
8496    private boolean removeTaskByIdLocked(int taskId, int flags) {
8497        TaskRecord tr = recentTaskForIdLocked(taskId);
8498        if (tr != null) {
8499            tr.removeTaskActivitiesLocked();
8500            cleanUpRemovedTaskLocked(tr, flags);
8501            if (tr.isPersistable) {
8502                notifyTaskPersisterLocked(null, true);
8503            }
8504            return true;
8505        }
8506        return false;
8507    }
8508
8509    @Override
8510    public boolean removeTask(int taskId, int flags) {
8511        synchronized (this) {
8512            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8513                    "removeTask()");
8514            long ident = Binder.clearCallingIdentity();
8515            try {
8516                return removeTaskByIdLocked(taskId, flags);
8517            } finally {
8518                Binder.restoreCallingIdentity(ident);
8519            }
8520        }
8521    }
8522
8523    /**
8524     * TODO: Add mController hook
8525     */
8526    @Override
8527    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8528        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8529                "moveTaskToFront()");
8530
8531        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8532        synchronized(this) {
8533            moveTaskToFrontLocked(taskId, flags, options);
8534        }
8535    }
8536
8537    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8538        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8539                Binder.getCallingUid(), -1, -1, "Task to front")) {
8540            ActivityOptions.abort(options);
8541            return;
8542        }
8543        final long origId = Binder.clearCallingIdentity();
8544        try {
8545            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8546            if (task == null) {
8547                return;
8548            }
8549            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8550                mStackSupervisor.showLockTaskToast();
8551                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8552                return;
8553            }
8554            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8555            if (prev != null && prev.isRecentsActivity()) {
8556                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8557            }
8558            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8559        } finally {
8560            Binder.restoreCallingIdentity(origId);
8561        }
8562        ActivityOptions.abort(options);
8563    }
8564
8565    @Override
8566    public void moveTaskToBack(int taskId) {
8567        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8568                "moveTaskToBack()");
8569
8570        synchronized(this) {
8571            TaskRecord tr = recentTaskForIdLocked(taskId);
8572            if (tr != null) {
8573                if (tr == mStackSupervisor.mLockTaskModeTask) {
8574                    mStackSupervisor.showLockTaskToast();
8575                    return;
8576                }
8577                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8578                ActivityStack stack = tr.stack;
8579                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8580                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8581                            Binder.getCallingUid(), -1, -1, "Task to back")) {
8582                        return;
8583                    }
8584                }
8585                final long origId = Binder.clearCallingIdentity();
8586                try {
8587                    stack.moveTaskToBackLocked(taskId, null);
8588                } finally {
8589                    Binder.restoreCallingIdentity(origId);
8590                }
8591            }
8592        }
8593    }
8594
8595    /**
8596     * Moves an activity, and all of the other activities within the same task, to the bottom
8597     * of the history stack.  The activity's order within the task is unchanged.
8598     *
8599     * @param token A reference to the activity we wish to move
8600     * @param nonRoot If false then this only works if the activity is the root
8601     *                of a task; if true it will work for any activity in a task.
8602     * @return Returns true if the move completed, false if not.
8603     */
8604    @Override
8605    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8606        enforceNotIsolatedCaller("moveActivityTaskToBack");
8607        synchronized(this) {
8608            final long origId = Binder.clearCallingIdentity();
8609            try {
8610                int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8611                if (taskId >= 0) {
8612                    if ((mStackSupervisor.mLockTaskModeTask != null)
8613                            && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8614                        mStackSupervisor.showLockTaskToast();
8615                        return false;
8616                    }
8617                    return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8618                }
8619            } finally {
8620                Binder.restoreCallingIdentity(origId);
8621            }
8622        }
8623        return false;
8624    }
8625
8626    @Override
8627    public void moveTaskBackwards(int task) {
8628        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8629                "moveTaskBackwards()");
8630
8631        synchronized(this) {
8632            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8633                    Binder.getCallingUid(), -1, -1, "Task backwards")) {
8634                return;
8635            }
8636            final long origId = Binder.clearCallingIdentity();
8637            moveTaskBackwardsLocked(task);
8638            Binder.restoreCallingIdentity(origId);
8639        }
8640    }
8641
8642    private final void moveTaskBackwardsLocked(int task) {
8643        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8644    }
8645
8646    @Override
8647    public IBinder getHomeActivityToken() throws RemoteException {
8648        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8649                "getHomeActivityToken()");
8650        synchronized (this) {
8651            return mStackSupervisor.getHomeActivityToken();
8652        }
8653    }
8654
8655    @Override
8656    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8657            IActivityContainerCallback callback) throws RemoteException {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "createActivityContainer()");
8660        synchronized (this) {
8661            if (parentActivityToken == null) {
8662                throw new IllegalArgumentException("parent token must not be null");
8663            }
8664            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8665            if (r == null) {
8666                return null;
8667            }
8668            if (callback == null) {
8669                throw new IllegalArgumentException("callback must not be null");
8670            }
8671            return mStackSupervisor.createActivityContainer(r, callback);
8672        }
8673    }
8674
8675    @Override
8676    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8677        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8678                "deleteActivityContainer()");
8679        synchronized (this) {
8680            mStackSupervisor.deleteActivityContainer(container);
8681        }
8682    }
8683
8684    @Override
8685    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8686            throws RemoteException {
8687        synchronized (this) {
8688            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8689            if (stack != null) {
8690                return stack.mActivityContainer;
8691            }
8692            return null;
8693        }
8694    }
8695
8696    @Override
8697    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8698        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8699                "moveTaskToStack()");
8700        if (stackId == HOME_STACK_ID) {
8701            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8702                    new RuntimeException("here").fillInStackTrace());
8703        }
8704        synchronized (this) {
8705            long ident = Binder.clearCallingIdentity();
8706            try {
8707                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8708                        + stackId + " toTop=" + toTop);
8709                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8710            } finally {
8711                Binder.restoreCallingIdentity(ident);
8712            }
8713        }
8714    }
8715
8716    @Override
8717    public void resizeStack(int stackBoxId, Rect bounds) {
8718        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8719                "resizeStackBox()");
8720        long ident = Binder.clearCallingIdentity();
8721        try {
8722            mWindowManager.resizeStack(stackBoxId, bounds);
8723        } finally {
8724            Binder.restoreCallingIdentity(ident);
8725        }
8726    }
8727
8728    @Override
8729    public List<StackInfo> getAllStackInfos() {
8730        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8731                "getAllStackInfos()");
8732        long ident = Binder.clearCallingIdentity();
8733        try {
8734            synchronized (this) {
8735                return mStackSupervisor.getAllStackInfosLocked();
8736            }
8737        } finally {
8738            Binder.restoreCallingIdentity(ident);
8739        }
8740    }
8741
8742    @Override
8743    public StackInfo getStackInfo(int stackId) {
8744        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8745                "getStackInfo()");
8746        long ident = Binder.clearCallingIdentity();
8747        try {
8748            synchronized (this) {
8749                return mStackSupervisor.getStackInfoLocked(stackId);
8750            }
8751        } finally {
8752            Binder.restoreCallingIdentity(ident);
8753        }
8754    }
8755
8756    @Override
8757    public boolean isInHomeStack(int taskId) {
8758        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8759                "getStackInfo()");
8760        long ident = Binder.clearCallingIdentity();
8761        try {
8762            synchronized (this) {
8763                TaskRecord tr = recentTaskForIdLocked(taskId);
8764                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8765            }
8766        } finally {
8767            Binder.restoreCallingIdentity(ident);
8768        }
8769    }
8770
8771    @Override
8772    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8773        synchronized(this) {
8774            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8775        }
8776    }
8777
8778    private boolean isLockTaskAuthorized(String pkg) {
8779        final DevicePolicyManager dpm = (DevicePolicyManager)
8780                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8781        try {
8782            int uid = mContext.getPackageManager().getPackageUid(pkg,
8783                    Binder.getCallingUserHandle().getIdentifier());
8784            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8785        } catch (NameNotFoundException e) {
8786            return false;
8787        }
8788    }
8789
8790    void startLockTaskMode(TaskRecord task) {
8791        final String pkg;
8792        synchronized (this) {
8793            pkg = task.intent.getComponent().getPackageName();
8794        }
8795        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8796        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8797            final TaskRecord taskRecord = task;
8798            mHandler.post(new Runnable() {
8799                @Override
8800                public void run() {
8801                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8802                }
8803            });
8804            return;
8805        }
8806        long ident = Binder.clearCallingIdentity();
8807        try {
8808            synchronized (this) {
8809                // Since we lost lock on task, make sure it is still there.
8810                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8811                if (task != null) {
8812                    if (!isSystemInitiated
8813                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8814                        throw new IllegalArgumentException("Invalid task, not in foreground");
8815                    }
8816                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8817                }
8818            }
8819        } finally {
8820            Binder.restoreCallingIdentity(ident);
8821        }
8822    }
8823
8824    @Override
8825    public void startLockTaskMode(int taskId) {
8826        final TaskRecord task;
8827        long ident = Binder.clearCallingIdentity();
8828        try {
8829            synchronized (this) {
8830                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8831            }
8832        } finally {
8833            Binder.restoreCallingIdentity(ident);
8834        }
8835        if (task != null) {
8836            startLockTaskMode(task);
8837        }
8838    }
8839
8840    @Override
8841    public void startLockTaskMode(IBinder token) {
8842        final TaskRecord task;
8843        long ident = Binder.clearCallingIdentity();
8844        try {
8845            synchronized (this) {
8846                final ActivityRecord r = ActivityRecord.forToken(token);
8847                if (r == null) {
8848                    return;
8849                }
8850                task = r.task;
8851            }
8852        } finally {
8853            Binder.restoreCallingIdentity(ident);
8854        }
8855        if (task != null) {
8856            startLockTaskMode(task);
8857        }
8858    }
8859
8860    @Override
8861    public void startLockTaskModeOnCurrent() throws RemoteException {
8862        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8863                "startLockTaskModeOnCurrent");
8864        ActivityRecord r = null;
8865        synchronized (this) {
8866            r = mStackSupervisor.topRunningActivityLocked();
8867        }
8868        startLockTaskMode(r.task);
8869    }
8870
8871    @Override
8872    public void stopLockTaskMode() {
8873        // Verify that the user matches the package of the intent for the TaskRecord
8874        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8875        // and stopLockTaskMode.
8876        final int callingUid = Binder.getCallingUid();
8877        if (callingUid != Process.SYSTEM_UID) {
8878            try {
8879                String pkg =
8880                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8881                int uid = mContext.getPackageManager().getPackageUid(pkg,
8882                        Binder.getCallingUserHandle().getIdentifier());
8883                if (uid != callingUid) {
8884                    throw new SecurityException("Invalid uid, expected " + uid);
8885                }
8886            } catch (NameNotFoundException e) {
8887                Log.d(TAG, "stopLockTaskMode " + e);
8888                return;
8889            }
8890        }
8891        long ident = Binder.clearCallingIdentity();
8892        try {
8893            Log.d(TAG, "stopLockTaskMode");
8894            // Stop lock task
8895            synchronized (this) {
8896                mStackSupervisor.setLockTaskModeLocked(null, false);
8897            }
8898        } finally {
8899            Binder.restoreCallingIdentity(ident);
8900        }
8901    }
8902
8903    @Override
8904    public void stopLockTaskModeOnCurrent() throws RemoteException {
8905        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8906                "stopLockTaskModeOnCurrent");
8907        long ident = Binder.clearCallingIdentity();
8908        try {
8909            stopLockTaskMode();
8910        } finally {
8911            Binder.restoreCallingIdentity(ident);
8912        }
8913    }
8914
8915    @Override
8916    public boolean isInLockTaskMode() {
8917        synchronized (this) {
8918            return mStackSupervisor.isInLockTaskMode();
8919        }
8920    }
8921
8922    // =========================================================
8923    // CONTENT PROVIDERS
8924    // =========================================================
8925
8926    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8927        List<ProviderInfo> providers = null;
8928        try {
8929            providers = AppGlobals.getPackageManager().
8930                queryContentProviders(app.processName, app.uid,
8931                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8932        } catch (RemoteException ex) {
8933        }
8934        if (DEBUG_MU)
8935            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8936        int userId = app.userId;
8937        if (providers != null) {
8938            int N = providers.size();
8939            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8940            for (int i=0; i<N; i++) {
8941                ProviderInfo cpi =
8942                    (ProviderInfo)providers.get(i);
8943                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8944                        cpi.name, cpi.flags);
8945                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8946                    // This is a singleton provider, but a user besides the
8947                    // default user is asking to initialize a process it runs
8948                    // in...  well, no, it doesn't actually run in this process,
8949                    // it runs in the process of the default user.  Get rid of it.
8950                    providers.remove(i);
8951                    N--;
8952                    i--;
8953                    continue;
8954                }
8955
8956                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8957                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8958                if (cpr == null) {
8959                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8960                    mProviderMap.putProviderByClass(comp, cpr);
8961                }
8962                if (DEBUG_MU)
8963                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8964                app.pubProviders.put(cpi.name, cpr);
8965                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8966                    // Don't add this if it is a platform component that is marked
8967                    // to run in multiple processes, because this is actually
8968                    // part of the framework so doesn't make sense to track as a
8969                    // separate apk in the process.
8970                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8971                            mProcessStats);
8972                }
8973                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8974            }
8975        }
8976        return providers;
8977    }
8978
8979    /**
8980     * Check if {@link ProcessRecord} has a possible chance at accessing the
8981     * given {@link ProviderInfo}. Final permission checking is always done
8982     * in {@link ContentProvider}.
8983     */
8984    private final String checkContentProviderPermissionLocked(
8985            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8986        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8987        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8988        boolean checkedGrants = false;
8989        if (checkUser) {
8990            // Looking for cross-user grants before enforcing the typical cross-users permissions
8991            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8992            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8993                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8994                    return null;
8995                }
8996                checkedGrants = true;
8997            }
8998            userId = handleIncomingUser(callingPid, callingUid, userId,
8999                    false, ALLOW_NON_FULL,
9000                    "checkContentProviderPermissionLocked " + cpi.authority, null);
9001            if (userId != tmpTargetUserId) {
9002                // When we actually went to determine the final targer user ID, this ended
9003                // up different than our initial check for the authority.  This is because
9004                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9005                // SELF.  So we need to re-check the grants again.
9006                checkedGrants = false;
9007            }
9008        }
9009        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9010                cpi.applicationInfo.uid, cpi.exported)
9011                == PackageManager.PERMISSION_GRANTED) {
9012            return null;
9013        }
9014        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9015                cpi.applicationInfo.uid, cpi.exported)
9016                == PackageManager.PERMISSION_GRANTED) {
9017            return null;
9018        }
9019
9020        PathPermission[] pps = cpi.pathPermissions;
9021        if (pps != null) {
9022            int i = pps.length;
9023            while (i > 0) {
9024                i--;
9025                PathPermission pp = pps[i];
9026                String pprperm = pp.getReadPermission();
9027                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9028                        cpi.applicationInfo.uid, cpi.exported)
9029                        == PackageManager.PERMISSION_GRANTED) {
9030                    return null;
9031                }
9032                String ppwperm = pp.getWritePermission();
9033                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9034                        cpi.applicationInfo.uid, cpi.exported)
9035                        == PackageManager.PERMISSION_GRANTED) {
9036                    return null;
9037                }
9038            }
9039        }
9040        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9041            return null;
9042        }
9043
9044        String msg;
9045        if (!cpi.exported) {
9046            msg = "Permission Denial: opening provider " + cpi.name
9047                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9048                    + ", uid=" + callingUid + ") that is not exported from uid "
9049                    + cpi.applicationInfo.uid;
9050        } else {
9051            msg = "Permission Denial: opening provider " + cpi.name
9052                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9053                    + ", uid=" + callingUid + ") requires "
9054                    + cpi.readPermission + " or " + cpi.writePermission;
9055        }
9056        Slog.w(TAG, msg);
9057        return msg;
9058    }
9059
9060    /**
9061     * Returns if the ContentProvider has granted a uri to callingUid
9062     */
9063    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9064        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9065        if (perms != null) {
9066            for (int i=perms.size()-1; i>=0; i--) {
9067                GrantUri grantUri = perms.keyAt(i);
9068                if (grantUri.sourceUserId == userId || !checkUser) {
9069                    if (matchesProvider(grantUri.uri, cpi)) {
9070                        return true;
9071                    }
9072                }
9073            }
9074        }
9075        return false;
9076    }
9077
9078    /**
9079     * Returns true if the uri authority is one of the authorities specified in the provider.
9080     */
9081    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9082        String uriAuth = uri.getAuthority();
9083        String cpiAuth = cpi.authority;
9084        if (cpiAuth.indexOf(';') == -1) {
9085            return cpiAuth.equals(uriAuth);
9086        }
9087        String[] cpiAuths = cpiAuth.split(";");
9088        int length = cpiAuths.length;
9089        for (int i = 0; i < length; i++) {
9090            if (cpiAuths[i].equals(uriAuth)) return true;
9091        }
9092        return false;
9093    }
9094
9095    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9096            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9097        if (r != null) {
9098            for (int i=0; i<r.conProviders.size(); i++) {
9099                ContentProviderConnection conn = r.conProviders.get(i);
9100                if (conn.provider == cpr) {
9101                    if (DEBUG_PROVIDER) Slog.v(TAG,
9102                            "Adding provider requested by "
9103                            + r.processName + " from process "
9104                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9105                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9106                    if (stable) {
9107                        conn.stableCount++;
9108                        conn.numStableIncs++;
9109                    } else {
9110                        conn.unstableCount++;
9111                        conn.numUnstableIncs++;
9112                    }
9113                    return conn;
9114                }
9115            }
9116            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9117            if (stable) {
9118                conn.stableCount = 1;
9119                conn.numStableIncs = 1;
9120            } else {
9121                conn.unstableCount = 1;
9122                conn.numUnstableIncs = 1;
9123            }
9124            cpr.connections.add(conn);
9125            r.conProviders.add(conn);
9126            return conn;
9127        }
9128        cpr.addExternalProcessHandleLocked(externalProcessToken);
9129        return null;
9130    }
9131
9132    boolean decProviderCountLocked(ContentProviderConnection conn,
9133            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9134        if (conn != null) {
9135            cpr = conn.provider;
9136            if (DEBUG_PROVIDER) Slog.v(TAG,
9137                    "Removing provider requested by "
9138                    + conn.client.processName + " from process "
9139                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9140                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9141            if (stable) {
9142                conn.stableCount--;
9143            } else {
9144                conn.unstableCount--;
9145            }
9146            if (conn.stableCount == 0 && conn.unstableCount == 0) {
9147                cpr.connections.remove(conn);
9148                conn.client.conProviders.remove(conn);
9149                return true;
9150            }
9151            return false;
9152        }
9153        cpr.removeExternalProcessHandleLocked(externalProcessToken);
9154        return false;
9155    }
9156
9157    private void checkTime(long startTime, String where) {
9158        long now = SystemClock.elapsedRealtime();
9159        if ((now-startTime) > 1000) {
9160            // If we are taking more than a second, log about it.
9161            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9162        }
9163    }
9164
9165    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9166            String name, IBinder token, boolean stable, int userId) {
9167        ContentProviderRecord cpr;
9168        ContentProviderConnection conn = null;
9169        ProviderInfo cpi = null;
9170
9171        synchronized(this) {
9172            long startTime = SystemClock.elapsedRealtime();
9173
9174            ProcessRecord r = null;
9175            if (caller != null) {
9176                r = getRecordForAppLocked(caller);
9177                if (r == null) {
9178                    throw new SecurityException(
9179                            "Unable to find app for caller " + caller
9180                          + " (pid=" + Binder.getCallingPid()
9181                          + ") when getting content provider " + name);
9182                }
9183            }
9184
9185            boolean checkCrossUser = true;
9186
9187            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9188
9189            // First check if this content provider has been published...
9190            cpr = mProviderMap.getProviderByName(name, userId);
9191            // If that didn't work, check if it exists for user 0 and then
9192            // verify that it's a singleton provider before using it.
9193            if (cpr == null && userId != UserHandle.USER_OWNER) {
9194                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9195                if (cpr != null) {
9196                    cpi = cpr.info;
9197                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9198                            cpi.name, cpi.flags)
9199                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9200                        userId = UserHandle.USER_OWNER;
9201                        checkCrossUser = false;
9202                    } else {
9203                        cpr = null;
9204                        cpi = null;
9205                    }
9206                }
9207            }
9208
9209            boolean providerRunning = cpr != null;
9210            if (providerRunning) {
9211                cpi = cpr.info;
9212                String msg;
9213                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9214                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9215                        != null) {
9216                    throw new SecurityException(msg);
9217                }
9218                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9219
9220                if (r != null && cpr.canRunHere(r)) {
9221                    // This provider has been published or is in the process
9222                    // of being published...  but it is also allowed to run
9223                    // in the caller's process, so don't make a connection
9224                    // and just let the caller instantiate its own instance.
9225                    ContentProviderHolder holder = cpr.newHolder(null);
9226                    // don't give caller the provider object, it needs
9227                    // to make its own.
9228                    holder.provider = null;
9229                    return holder;
9230                }
9231
9232                final long origId = Binder.clearCallingIdentity();
9233
9234                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9235
9236                // In this case the provider instance already exists, so we can
9237                // return it right away.
9238                conn = incProviderCountLocked(r, cpr, token, stable);
9239                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9240                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9241                        // If this is a perceptible app accessing the provider,
9242                        // make sure to count it as being accessed and thus
9243                        // back up on the LRU list.  This is good because
9244                        // content providers are often expensive to start.
9245                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9246                        updateLruProcessLocked(cpr.proc, false, null);
9247                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9248                    }
9249                }
9250
9251                if (cpr.proc != null) {
9252                    if (false) {
9253                        if (cpr.name.flattenToShortString().equals(
9254                                "com.android.providers.calendar/.CalendarProvider2")) {
9255                            Slog.v(TAG, "****************** KILLING "
9256                                + cpr.name.flattenToShortString());
9257                            Process.killProcess(cpr.proc.pid);
9258                        }
9259                    }
9260                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9261                    boolean success = updateOomAdjLocked(cpr.proc);
9262                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9263                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9264                    // NOTE: there is still a race here where a signal could be
9265                    // pending on the process even though we managed to update its
9266                    // adj level.  Not sure what to do about this, but at least
9267                    // the race is now smaller.
9268                    if (!success) {
9269                        // Uh oh...  it looks like the provider's process
9270                        // has been killed on us.  We need to wait for a new
9271                        // process to be started, and make sure its death
9272                        // doesn't kill our process.
9273                        Slog.i(TAG,
9274                                "Existing provider " + cpr.name.flattenToShortString()
9275                                + " is crashing; detaching " + r);
9276                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9277                        checkTime(startTime, "getContentProviderImpl: before appDied");
9278                        appDiedLocked(cpr.proc);
9279                        checkTime(startTime, "getContentProviderImpl: after appDied");
9280                        if (!lastRef) {
9281                            // This wasn't the last ref our process had on
9282                            // the provider...  we have now been killed, bail.
9283                            return null;
9284                        }
9285                        providerRunning = false;
9286                        conn = null;
9287                    }
9288                }
9289
9290                Binder.restoreCallingIdentity(origId);
9291            }
9292
9293            boolean singleton;
9294            if (!providerRunning) {
9295                try {
9296                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9297                    cpi = AppGlobals.getPackageManager().
9298                        resolveContentProvider(name,
9299                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9300                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9301                } catch (RemoteException ex) {
9302                }
9303                if (cpi == null) {
9304                    return null;
9305                }
9306                // If the provider is a singleton AND
9307                // (it's a call within the same user || the provider is a
9308                // privileged app)
9309                // Then allow connecting to the singleton provider
9310                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9311                        cpi.name, cpi.flags)
9312                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9313                if (singleton) {
9314                    userId = UserHandle.USER_OWNER;
9315                }
9316                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9317                checkTime(startTime, "getContentProviderImpl: got app info for user");
9318
9319                String msg;
9320                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9321                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9322                        != null) {
9323                    throw new SecurityException(msg);
9324                }
9325                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9326
9327                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9328                        && !cpi.processName.equals("system")) {
9329                    // If this content provider does not run in the system
9330                    // process, and the system is not yet ready to run other
9331                    // processes, then fail fast instead of hanging.
9332                    throw new IllegalArgumentException(
9333                            "Attempt to launch content provider before system ready");
9334                }
9335
9336                // Make sure that the user who owns this provider is started.  If not,
9337                // we don't want to allow it to run.
9338                if (mStartedUsers.get(userId) == null) {
9339                    Slog.w(TAG, "Unable to launch app "
9340                            + cpi.applicationInfo.packageName + "/"
9341                            + cpi.applicationInfo.uid + " for provider "
9342                            + name + ": user " + userId + " is stopped");
9343                    return null;
9344                }
9345
9346                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9347                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9348                cpr = mProviderMap.getProviderByClass(comp, userId);
9349                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9350                final boolean firstClass = cpr == null;
9351                if (firstClass) {
9352                    try {
9353                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9354                        ApplicationInfo ai =
9355                            AppGlobals.getPackageManager().
9356                                getApplicationInfo(
9357                                        cpi.applicationInfo.packageName,
9358                                        STOCK_PM_FLAGS, userId);
9359                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9360                        if (ai == null) {
9361                            Slog.w(TAG, "No package info for content provider "
9362                                    + cpi.name);
9363                            return null;
9364                        }
9365                        ai = getAppInfoForUser(ai, userId);
9366                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9367                    } catch (RemoteException ex) {
9368                        // pm is in same process, this will never happen.
9369                    }
9370                }
9371
9372                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9373
9374                if (r != null && cpr.canRunHere(r)) {
9375                    // If this is a multiprocess provider, then just return its
9376                    // info and allow the caller to instantiate it.  Only do
9377                    // this if the provider is the same user as the caller's
9378                    // process, or can run as root (so can be in any process).
9379                    return cpr.newHolder(null);
9380                }
9381
9382                if (DEBUG_PROVIDER) {
9383                    RuntimeException e = new RuntimeException("here");
9384                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9385                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9386                }
9387
9388                // This is single process, and our app is now connecting to it.
9389                // See if we are already in the process of launching this
9390                // provider.
9391                final int N = mLaunchingProviders.size();
9392                int i;
9393                for (i=0; i<N; i++) {
9394                    if (mLaunchingProviders.get(i) == cpr) {
9395                        break;
9396                    }
9397                }
9398
9399                // If the provider is not already being launched, then get it
9400                // started.
9401                if (i >= N) {
9402                    final long origId = Binder.clearCallingIdentity();
9403
9404                    try {
9405                        // Content provider is now in use, its package can't be stopped.
9406                        try {
9407                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9408                            AppGlobals.getPackageManager().setPackageStoppedState(
9409                                    cpr.appInfo.packageName, false, userId);
9410                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9411                        } catch (RemoteException e) {
9412                        } catch (IllegalArgumentException e) {
9413                            Slog.w(TAG, "Failed trying to unstop package "
9414                                    + cpr.appInfo.packageName + ": " + e);
9415                        }
9416
9417                        // Use existing process if already started
9418                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9419                        ProcessRecord proc = getProcessRecordLocked(
9420                                cpi.processName, cpr.appInfo.uid, false);
9421                        if (proc != null && proc.thread != null) {
9422                            if (DEBUG_PROVIDER) {
9423                                Slog.d(TAG, "Installing in existing process " + proc);
9424                            }
9425                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9426                            proc.pubProviders.put(cpi.name, cpr);
9427                            try {
9428                                proc.thread.scheduleInstallProvider(cpi);
9429                            } catch (RemoteException e) {
9430                            }
9431                        } else {
9432                            checkTime(startTime, "getContentProviderImpl: before start process");
9433                            proc = startProcessLocked(cpi.processName,
9434                                    cpr.appInfo, false, 0, "content provider",
9435                                    new ComponentName(cpi.applicationInfo.packageName,
9436                                            cpi.name), false, false, false);
9437                            checkTime(startTime, "getContentProviderImpl: after start process");
9438                            if (proc == null) {
9439                                Slog.w(TAG, "Unable to launch app "
9440                                        + cpi.applicationInfo.packageName + "/"
9441                                        + cpi.applicationInfo.uid + " for provider "
9442                                        + name + ": process is bad");
9443                                return null;
9444                            }
9445                        }
9446                        cpr.launchingApp = proc;
9447                        mLaunchingProviders.add(cpr);
9448                    } finally {
9449                        Binder.restoreCallingIdentity(origId);
9450                    }
9451                }
9452
9453                checkTime(startTime, "getContentProviderImpl: updating data structures");
9454
9455                // Make sure the provider is published (the same provider class
9456                // may be published under multiple names).
9457                if (firstClass) {
9458                    mProviderMap.putProviderByClass(comp, cpr);
9459                }
9460
9461                mProviderMap.putProviderByName(name, cpr);
9462                conn = incProviderCountLocked(r, cpr, token, stable);
9463                if (conn != null) {
9464                    conn.waiting = true;
9465                }
9466            }
9467            checkTime(startTime, "getContentProviderImpl: done!");
9468        }
9469
9470        // Wait for the provider to be published...
9471        synchronized (cpr) {
9472            while (cpr.provider == null) {
9473                if (cpr.launchingApp == null) {
9474                    Slog.w(TAG, "Unable to launch app "
9475                            + cpi.applicationInfo.packageName + "/"
9476                            + cpi.applicationInfo.uid + " for provider "
9477                            + name + ": launching app became null");
9478                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9479                            UserHandle.getUserId(cpi.applicationInfo.uid),
9480                            cpi.applicationInfo.packageName,
9481                            cpi.applicationInfo.uid, name);
9482                    return null;
9483                }
9484                try {
9485                    if (DEBUG_MU) {
9486                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9487                                + cpr.launchingApp);
9488                    }
9489                    if (conn != null) {
9490                        conn.waiting = true;
9491                    }
9492                    cpr.wait();
9493                } catch (InterruptedException ex) {
9494                } finally {
9495                    if (conn != null) {
9496                        conn.waiting = false;
9497                    }
9498                }
9499            }
9500        }
9501        return cpr != null ? cpr.newHolder(conn) : null;
9502    }
9503
9504    @Override
9505    public final ContentProviderHolder getContentProvider(
9506            IApplicationThread caller, String name, int userId, boolean stable) {
9507        enforceNotIsolatedCaller("getContentProvider");
9508        if (caller == null) {
9509            String msg = "null IApplicationThread when getting content provider "
9510                    + name;
9511            Slog.w(TAG, msg);
9512            throw new SecurityException(msg);
9513        }
9514        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9515        // with cross-user grant.
9516        return getContentProviderImpl(caller, name, null, stable, userId);
9517    }
9518
9519    public ContentProviderHolder getContentProviderExternal(
9520            String name, int userId, IBinder token) {
9521        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9522            "Do not have permission in call getContentProviderExternal()");
9523        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9524                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9525        return getContentProviderExternalUnchecked(name, token, userId);
9526    }
9527
9528    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9529            IBinder token, int userId) {
9530        return getContentProviderImpl(null, name, token, true, userId);
9531    }
9532
9533    /**
9534     * Drop a content provider from a ProcessRecord's bookkeeping
9535     */
9536    public void removeContentProvider(IBinder connection, boolean stable) {
9537        enforceNotIsolatedCaller("removeContentProvider");
9538        long ident = Binder.clearCallingIdentity();
9539        try {
9540            synchronized (this) {
9541                ContentProviderConnection conn;
9542                try {
9543                    conn = (ContentProviderConnection)connection;
9544                } catch (ClassCastException e) {
9545                    String msg ="removeContentProvider: " + connection
9546                            + " not a ContentProviderConnection";
9547                    Slog.w(TAG, msg);
9548                    throw new IllegalArgumentException(msg);
9549                }
9550                if (conn == null) {
9551                    throw new NullPointerException("connection is null");
9552                }
9553                if (decProviderCountLocked(conn, null, null, stable)) {
9554                    updateOomAdjLocked();
9555                }
9556            }
9557        } finally {
9558            Binder.restoreCallingIdentity(ident);
9559        }
9560    }
9561
9562    public void removeContentProviderExternal(String name, IBinder token) {
9563        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9564            "Do not have permission in call removeContentProviderExternal()");
9565        int userId = UserHandle.getCallingUserId();
9566        long ident = Binder.clearCallingIdentity();
9567        try {
9568            removeContentProviderExternalUnchecked(name, token, userId);
9569        } finally {
9570            Binder.restoreCallingIdentity(ident);
9571        }
9572    }
9573
9574    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9575        synchronized (this) {
9576            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9577            if(cpr == null) {
9578                //remove from mProvidersByClass
9579                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9580                return;
9581            }
9582
9583            //update content provider record entry info
9584            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9585            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9586            if (localCpr.hasExternalProcessHandles()) {
9587                if (localCpr.removeExternalProcessHandleLocked(token)) {
9588                    updateOomAdjLocked();
9589                } else {
9590                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9591                            + " with no external reference for token: "
9592                            + token + ".");
9593                }
9594            } else {
9595                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9596                        + " with no external references.");
9597            }
9598        }
9599    }
9600
9601    public final void publishContentProviders(IApplicationThread caller,
9602            List<ContentProviderHolder> providers) {
9603        if (providers == null) {
9604            return;
9605        }
9606
9607        enforceNotIsolatedCaller("publishContentProviders");
9608        synchronized (this) {
9609            final ProcessRecord r = getRecordForAppLocked(caller);
9610            if (DEBUG_MU)
9611                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9612            if (r == null) {
9613                throw new SecurityException(
9614                        "Unable to find app for caller " + caller
9615                      + " (pid=" + Binder.getCallingPid()
9616                      + ") when publishing content providers");
9617            }
9618
9619            final long origId = Binder.clearCallingIdentity();
9620
9621            final int N = providers.size();
9622            for (int i=0; i<N; i++) {
9623                ContentProviderHolder src = providers.get(i);
9624                if (src == null || src.info == null || src.provider == null) {
9625                    continue;
9626                }
9627                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9628                if (DEBUG_MU)
9629                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9630                if (dst != null) {
9631                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9632                    mProviderMap.putProviderByClass(comp, dst);
9633                    String names[] = dst.info.authority.split(";");
9634                    for (int j = 0; j < names.length; j++) {
9635                        mProviderMap.putProviderByName(names[j], dst);
9636                    }
9637
9638                    int NL = mLaunchingProviders.size();
9639                    int j;
9640                    for (j=0; j<NL; j++) {
9641                        if (mLaunchingProviders.get(j) == dst) {
9642                            mLaunchingProviders.remove(j);
9643                            j--;
9644                            NL--;
9645                        }
9646                    }
9647                    synchronized (dst) {
9648                        dst.provider = src.provider;
9649                        dst.proc = r;
9650                        dst.notifyAll();
9651                    }
9652                    updateOomAdjLocked(r);
9653                }
9654            }
9655
9656            Binder.restoreCallingIdentity(origId);
9657        }
9658    }
9659
9660    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9661        ContentProviderConnection conn;
9662        try {
9663            conn = (ContentProviderConnection)connection;
9664        } catch (ClassCastException e) {
9665            String msg ="refContentProvider: " + connection
9666                    + " not a ContentProviderConnection";
9667            Slog.w(TAG, msg);
9668            throw new IllegalArgumentException(msg);
9669        }
9670        if (conn == null) {
9671            throw new NullPointerException("connection is null");
9672        }
9673
9674        synchronized (this) {
9675            if (stable > 0) {
9676                conn.numStableIncs += stable;
9677            }
9678            stable = conn.stableCount + stable;
9679            if (stable < 0) {
9680                throw new IllegalStateException("stableCount < 0: " + stable);
9681            }
9682
9683            if (unstable > 0) {
9684                conn.numUnstableIncs += unstable;
9685            }
9686            unstable = conn.unstableCount + unstable;
9687            if (unstable < 0) {
9688                throw new IllegalStateException("unstableCount < 0: " + unstable);
9689            }
9690
9691            if ((stable+unstable) <= 0) {
9692                throw new IllegalStateException("ref counts can't go to zero here: stable="
9693                        + stable + " unstable=" + unstable);
9694            }
9695            conn.stableCount = stable;
9696            conn.unstableCount = unstable;
9697            return !conn.dead;
9698        }
9699    }
9700
9701    public void unstableProviderDied(IBinder connection) {
9702        ContentProviderConnection conn;
9703        try {
9704            conn = (ContentProviderConnection)connection;
9705        } catch (ClassCastException e) {
9706            String msg ="refContentProvider: " + connection
9707                    + " not a ContentProviderConnection";
9708            Slog.w(TAG, msg);
9709            throw new IllegalArgumentException(msg);
9710        }
9711        if (conn == null) {
9712            throw new NullPointerException("connection is null");
9713        }
9714
9715        // Safely retrieve the content provider associated with the connection.
9716        IContentProvider provider;
9717        synchronized (this) {
9718            provider = conn.provider.provider;
9719        }
9720
9721        if (provider == null) {
9722            // Um, yeah, we're way ahead of you.
9723            return;
9724        }
9725
9726        // Make sure the caller is being honest with us.
9727        if (provider.asBinder().pingBinder()) {
9728            // Er, no, still looks good to us.
9729            synchronized (this) {
9730                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9731                        + " says " + conn + " died, but we don't agree");
9732                return;
9733            }
9734        }
9735
9736        // Well look at that!  It's dead!
9737        synchronized (this) {
9738            if (conn.provider.provider != provider) {
9739                // But something changed...  good enough.
9740                return;
9741            }
9742
9743            ProcessRecord proc = conn.provider.proc;
9744            if (proc == null || proc.thread == null) {
9745                // Seems like the process is already cleaned up.
9746                return;
9747            }
9748
9749            // As far as we're concerned, this is just like receiving a
9750            // death notification...  just a bit prematurely.
9751            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9752                    + ") early provider death");
9753            final long ident = Binder.clearCallingIdentity();
9754            try {
9755                appDiedLocked(proc);
9756            } finally {
9757                Binder.restoreCallingIdentity(ident);
9758            }
9759        }
9760    }
9761
9762    @Override
9763    public void appNotRespondingViaProvider(IBinder connection) {
9764        enforceCallingPermission(
9765                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9766
9767        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9768        if (conn == null) {
9769            Slog.w(TAG, "ContentProviderConnection is null");
9770            return;
9771        }
9772
9773        final ProcessRecord host = conn.provider.proc;
9774        if (host == null) {
9775            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9776            return;
9777        }
9778
9779        final long token = Binder.clearCallingIdentity();
9780        try {
9781            appNotResponding(host, null, null, false, "ContentProvider not responding");
9782        } finally {
9783            Binder.restoreCallingIdentity(token);
9784        }
9785    }
9786
9787    public final void installSystemProviders() {
9788        List<ProviderInfo> providers;
9789        synchronized (this) {
9790            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9791            providers = generateApplicationProvidersLocked(app);
9792            if (providers != null) {
9793                for (int i=providers.size()-1; i>=0; i--) {
9794                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9795                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9796                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9797                                + ": not system .apk");
9798                        providers.remove(i);
9799                    }
9800                }
9801            }
9802        }
9803        if (providers != null) {
9804            mSystemThread.installSystemProviders(providers);
9805        }
9806
9807        mCoreSettingsObserver = new CoreSettingsObserver(this);
9808
9809        //mUsageStatsService.monitorPackages();
9810    }
9811
9812    /**
9813     * Allows apps to retrieve the MIME type of a URI.
9814     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9815     * users, then it does not need permission to access the ContentProvider.
9816     * Either, it needs cross-user uri grants.
9817     *
9818     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9819     *
9820     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9821     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9822     */
9823    public String getProviderMimeType(Uri uri, int userId) {
9824        enforceNotIsolatedCaller("getProviderMimeType");
9825        final String name = uri.getAuthority();
9826        int callingUid = Binder.getCallingUid();
9827        int callingPid = Binder.getCallingPid();
9828        long ident = 0;
9829        boolean clearedIdentity = false;
9830        userId = unsafeConvertIncomingUser(userId);
9831        if (canClearIdentity(callingPid, callingUid, userId)) {
9832            clearedIdentity = true;
9833            ident = Binder.clearCallingIdentity();
9834        }
9835        ContentProviderHolder holder = null;
9836        try {
9837            holder = getContentProviderExternalUnchecked(name, null, userId);
9838            if (holder != null) {
9839                return holder.provider.getType(uri);
9840            }
9841        } catch (RemoteException e) {
9842            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9843            return null;
9844        } finally {
9845            // We need to clear the identity to call removeContentProviderExternalUnchecked
9846            if (!clearedIdentity) {
9847                ident = Binder.clearCallingIdentity();
9848            }
9849            try {
9850                if (holder != null) {
9851                    removeContentProviderExternalUnchecked(name, null, userId);
9852                }
9853            } finally {
9854                Binder.restoreCallingIdentity(ident);
9855            }
9856        }
9857
9858        return null;
9859    }
9860
9861    private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9862        if (UserHandle.getUserId(callingUid) == userId) {
9863            return true;
9864        }
9865        if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9866                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9867                || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9868                callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9869                return true;
9870        }
9871        return false;
9872    }
9873
9874    // =========================================================
9875    // GLOBAL MANAGEMENT
9876    // =========================================================
9877
9878    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9879            boolean isolated, int isolatedUid) {
9880        String proc = customProcess != null ? customProcess : info.processName;
9881        BatteryStatsImpl.Uid.Proc ps = null;
9882        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9883        int uid = info.uid;
9884        if (isolated) {
9885            if (isolatedUid == 0) {
9886                int userId = UserHandle.getUserId(uid);
9887                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9888                while (true) {
9889                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9890                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9891                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9892                    }
9893                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9894                    mNextIsolatedProcessUid++;
9895                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9896                        // No process for this uid, use it.
9897                        break;
9898                    }
9899                    stepsLeft--;
9900                    if (stepsLeft <= 0) {
9901                        return null;
9902                    }
9903                }
9904            } else {
9905                // Special case for startIsolatedProcess (internal only), where
9906                // the uid of the isolated process is specified by the caller.
9907                uid = isolatedUid;
9908            }
9909        }
9910        return new ProcessRecord(stats, info, proc, uid);
9911    }
9912
9913    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9914            String abiOverride) {
9915        ProcessRecord app;
9916        if (!isolated) {
9917            app = getProcessRecordLocked(info.processName, info.uid, true);
9918        } else {
9919            app = null;
9920        }
9921
9922        if (app == null) {
9923            app = newProcessRecordLocked(info, null, isolated, 0);
9924            mProcessNames.put(info.processName, app.uid, app);
9925            if (isolated) {
9926                mIsolatedProcesses.put(app.uid, app);
9927            }
9928            updateLruProcessLocked(app, false, null);
9929            updateOomAdjLocked();
9930        }
9931
9932        // This package really, really can not be stopped.
9933        try {
9934            AppGlobals.getPackageManager().setPackageStoppedState(
9935                    info.packageName, false, UserHandle.getUserId(app.uid));
9936        } catch (RemoteException e) {
9937        } catch (IllegalArgumentException e) {
9938            Slog.w(TAG, "Failed trying to unstop package "
9939                    + info.packageName + ": " + e);
9940        }
9941
9942        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9943                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9944            app.persistent = true;
9945            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9946        }
9947        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9948            mPersistentStartingProcesses.add(app);
9949            startProcessLocked(app, "added application", app.processName, abiOverride,
9950                    null /* entryPoint */, null /* entryPointArgs */);
9951        }
9952
9953        return app;
9954    }
9955
9956    public void unhandledBack() {
9957        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9958                "unhandledBack()");
9959
9960        synchronized(this) {
9961            final long origId = Binder.clearCallingIdentity();
9962            try {
9963                getFocusedStack().unhandledBackLocked();
9964            } finally {
9965                Binder.restoreCallingIdentity(origId);
9966            }
9967        }
9968    }
9969
9970    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9971        enforceNotIsolatedCaller("openContentUri");
9972        final int userId = UserHandle.getCallingUserId();
9973        String name = uri.getAuthority();
9974        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9975        ParcelFileDescriptor pfd = null;
9976        if (cph != null) {
9977            // We record the binder invoker's uid in thread-local storage before
9978            // going to the content provider to open the file.  Later, in the code
9979            // that handles all permissions checks, we look for this uid and use
9980            // that rather than the Activity Manager's own uid.  The effect is that
9981            // we do the check against the caller's permissions even though it looks
9982            // to the content provider like the Activity Manager itself is making
9983            // the request.
9984            sCallerIdentity.set(new Identity(
9985                    Binder.getCallingPid(), Binder.getCallingUid()));
9986            try {
9987                pfd = cph.provider.openFile(null, uri, "r", null);
9988            } catch (FileNotFoundException e) {
9989                // do nothing; pfd will be returned null
9990            } finally {
9991                // Ensure that whatever happens, we clean up the identity state
9992                sCallerIdentity.remove();
9993            }
9994
9995            // We've got the fd now, so we're done with the provider.
9996            removeContentProviderExternalUnchecked(name, null, userId);
9997        } else {
9998            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9999        }
10000        return pfd;
10001    }
10002
10003    // Actually is sleeping or shutting down or whatever else in the future
10004    // is an inactive state.
10005    public boolean isSleepingOrShuttingDown() {
10006        return isSleeping() || mShuttingDown;
10007    }
10008
10009    public boolean isSleeping() {
10010        return mSleeping;
10011    }
10012
10013    void goingToSleep() {
10014        synchronized(this) {
10015            mWentToSleep = true;
10016            goToSleepIfNeededLocked();
10017        }
10018    }
10019
10020    void finishRunningVoiceLocked() {
10021        if (mRunningVoice) {
10022            mRunningVoice = false;
10023            goToSleepIfNeededLocked();
10024        }
10025    }
10026
10027    void goToSleepIfNeededLocked() {
10028        if (mWentToSleep && !mRunningVoice) {
10029            if (!mSleeping) {
10030                mSleeping = true;
10031                mStackSupervisor.goingToSleepLocked();
10032
10033                // Initialize the wake times of all processes.
10034                checkExcessivePowerUsageLocked(false);
10035                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10036                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10037                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10038            }
10039        }
10040    }
10041
10042    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10043        if (task != null && task.stack != null && task.stack.isHomeStack()) {
10044            // Never persist the home stack.
10045            return;
10046        }
10047        mTaskPersister.wakeup(task, flush);
10048    }
10049
10050    @Override
10051    public boolean shutdown(int timeout) {
10052        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10053                != PackageManager.PERMISSION_GRANTED) {
10054            throw new SecurityException("Requires permission "
10055                    + android.Manifest.permission.SHUTDOWN);
10056        }
10057
10058        boolean timedout = false;
10059
10060        synchronized(this) {
10061            mShuttingDown = true;
10062            updateEventDispatchingLocked();
10063            timedout = mStackSupervisor.shutdownLocked(timeout);
10064        }
10065
10066        mAppOpsService.shutdown();
10067        if (mUsageStatsService != null) {
10068            mUsageStatsService.prepareShutdown();
10069        }
10070        mBatteryStatsService.shutdown();
10071        synchronized (this) {
10072            mProcessStats.shutdownLocked();
10073        }
10074        notifyTaskPersisterLocked(null, true);
10075
10076        return timedout;
10077    }
10078
10079    public final void activitySlept(IBinder token) {
10080        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10081
10082        final long origId = Binder.clearCallingIdentity();
10083
10084        synchronized (this) {
10085            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10086            if (r != null) {
10087                mStackSupervisor.activitySleptLocked(r);
10088            }
10089        }
10090
10091        Binder.restoreCallingIdentity(origId);
10092    }
10093
10094    void logLockScreen(String msg) {
10095        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
10096                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
10097                mWentToSleep + " mSleeping=" + mSleeping);
10098    }
10099
10100    private void comeOutOfSleepIfNeededLocked() {
10101        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
10102            if (mSleeping) {
10103                mSleeping = false;
10104                mStackSupervisor.comeOutOfSleepIfNeededLocked();
10105            }
10106        }
10107    }
10108
10109    void wakingUp() {
10110        synchronized(this) {
10111            mWentToSleep = false;
10112            comeOutOfSleepIfNeededLocked();
10113        }
10114    }
10115
10116    void startRunningVoiceLocked() {
10117        if (!mRunningVoice) {
10118            mRunningVoice = true;
10119            comeOutOfSleepIfNeededLocked();
10120        }
10121    }
10122
10123    private void updateEventDispatchingLocked() {
10124        mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10125    }
10126
10127    public void setLockScreenShown(boolean shown) {
10128        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10129                != PackageManager.PERMISSION_GRANTED) {
10130            throw new SecurityException("Requires permission "
10131                    + android.Manifest.permission.DEVICE_POWER);
10132        }
10133
10134        synchronized(this) {
10135            long ident = Binder.clearCallingIdentity();
10136            try {
10137                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10138                mLockScreenShown = shown;
10139                comeOutOfSleepIfNeededLocked();
10140            } finally {
10141                Binder.restoreCallingIdentity(ident);
10142            }
10143        }
10144    }
10145
10146    @Override
10147    public void stopAppSwitches() {
10148        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10149                != PackageManager.PERMISSION_GRANTED) {
10150            throw new SecurityException("Requires permission "
10151                    + android.Manifest.permission.STOP_APP_SWITCHES);
10152        }
10153
10154        synchronized(this) {
10155            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10156                    + APP_SWITCH_DELAY_TIME;
10157            mDidAppSwitch = false;
10158            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10159            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10160            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10161        }
10162    }
10163
10164    public void resumeAppSwitches() {
10165        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10166                != PackageManager.PERMISSION_GRANTED) {
10167            throw new SecurityException("Requires permission "
10168                    + android.Manifest.permission.STOP_APP_SWITCHES);
10169        }
10170
10171        synchronized(this) {
10172            // Note that we don't execute any pending app switches... we will
10173            // let those wait until either the timeout, or the next start
10174            // activity request.
10175            mAppSwitchesAllowedTime = 0;
10176        }
10177    }
10178
10179    boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10180            int callingPid, int callingUid, String name) {
10181        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10182            return true;
10183        }
10184
10185        int perm = checkComponentPermission(
10186                android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10187                sourceUid, -1, true);
10188        if (perm == PackageManager.PERMISSION_GRANTED) {
10189            return true;
10190        }
10191
10192        // If the actual IPC caller is different from the logical source, then
10193        // also see if they are allowed to control app switches.
10194        if (callingUid != -1 && callingUid != sourceUid) {
10195            perm = checkComponentPermission(
10196                    android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10197                    callingUid, -1, true);
10198            if (perm == PackageManager.PERMISSION_GRANTED) {
10199                return true;
10200            }
10201        }
10202
10203        Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10204        return false;
10205    }
10206
10207    public void setDebugApp(String packageName, boolean waitForDebugger,
10208            boolean persistent) {
10209        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10210                "setDebugApp()");
10211
10212        long ident = Binder.clearCallingIdentity();
10213        try {
10214            // Note that this is not really thread safe if there are multiple
10215            // callers into it at the same time, but that's not a situation we
10216            // care about.
10217            if (persistent) {
10218                final ContentResolver resolver = mContext.getContentResolver();
10219                Settings.Global.putString(
10220                    resolver, Settings.Global.DEBUG_APP,
10221                    packageName);
10222                Settings.Global.putInt(
10223                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10224                    waitForDebugger ? 1 : 0);
10225            }
10226
10227            synchronized (this) {
10228                if (!persistent) {
10229                    mOrigDebugApp = mDebugApp;
10230                    mOrigWaitForDebugger = mWaitForDebugger;
10231                }
10232                mDebugApp = packageName;
10233                mWaitForDebugger = waitForDebugger;
10234                mDebugTransient = !persistent;
10235                if (packageName != null) {
10236                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10237                            false, UserHandle.USER_ALL, "set debug app");
10238                }
10239            }
10240        } finally {
10241            Binder.restoreCallingIdentity(ident);
10242        }
10243    }
10244
10245    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10246        synchronized (this) {
10247            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10248            if (!isDebuggable) {
10249                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10250                    throw new SecurityException("Process not debuggable: " + app.packageName);
10251                }
10252            }
10253
10254            mOpenGlTraceApp = processName;
10255        }
10256    }
10257
10258    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10259        synchronized (this) {
10260            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10261            if (!isDebuggable) {
10262                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10263                    throw new SecurityException("Process not debuggable: " + app.packageName);
10264                }
10265            }
10266            mProfileApp = processName;
10267            mProfileFile = profilerInfo.profileFile;
10268            if (mProfileFd != null) {
10269                try {
10270                    mProfileFd.close();
10271                } catch (IOException e) {
10272                }
10273                mProfileFd = null;
10274            }
10275            mProfileFd = profilerInfo.profileFd;
10276            mSamplingInterval = profilerInfo.samplingInterval;
10277            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10278            mProfileType = 0;
10279        }
10280    }
10281
10282    @Override
10283    public void setAlwaysFinish(boolean enabled) {
10284        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10285                "setAlwaysFinish()");
10286
10287        Settings.Global.putInt(
10288                mContext.getContentResolver(),
10289                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10290
10291        synchronized (this) {
10292            mAlwaysFinishActivities = enabled;
10293        }
10294    }
10295
10296    @Override
10297    public void setActivityController(IActivityController controller) {
10298        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10299                "setActivityController()");
10300        synchronized (this) {
10301            mController = controller;
10302            Watchdog.getInstance().setActivityController(controller);
10303        }
10304    }
10305
10306    @Override
10307    public void setUserIsMonkey(boolean userIsMonkey) {
10308        synchronized (this) {
10309            synchronized (mPidsSelfLocked) {
10310                final int callingPid = Binder.getCallingPid();
10311                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10312                if (precessRecord == null) {
10313                    throw new SecurityException("Unknown process: " + callingPid);
10314                }
10315                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10316                    throw new SecurityException("Only an instrumentation process "
10317                            + "with a UiAutomation can call setUserIsMonkey");
10318                }
10319            }
10320            mUserIsMonkey = userIsMonkey;
10321        }
10322    }
10323
10324    @Override
10325    public boolean isUserAMonkey() {
10326        synchronized (this) {
10327            // If there is a controller also implies the user is a monkey.
10328            return (mUserIsMonkey || mController != null);
10329        }
10330    }
10331
10332    public void requestBugReport() {
10333        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10334        SystemProperties.set("ctl.start", "bugreport");
10335    }
10336
10337    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10338        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10339    }
10340
10341    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10342        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10343            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10344        }
10345        return KEY_DISPATCHING_TIMEOUT;
10346    }
10347
10348    @Override
10349    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10350        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10351                != PackageManager.PERMISSION_GRANTED) {
10352            throw new SecurityException("Requires permission "
10353                    + android.Manifest.permission.FILTER_EVENTS);
10354        }
10355        ProcessRecord proc;
10356        long timeout;
10357        synchronized (this) {
10358            synchronized (mPidsSelfLocked) {
10359                proc = mPidsSelfLocked.get(pid);
10360            }
10361            timeout = getInputDispatchingTimeoutLocked(proc);
10362        }
10363
10364        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10365            return -1;
10366        }
10367
10368        return timeout;
10369    }
10370
10371    /**
10372     * Handle input dispatching timeouts.
10373     * Returns whether input dispatching should be aborted or not.
10374     */
10375    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10376            final ActivityRecord activity, final ActivityRecord parent,
10377            final boolean aboveSystem, String reason) {
10378        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10379                != PackageManager.PERMISSION_GRANTED) {
10380            throw new SecurityException("Requires permission "
10381                    + android.Manifest.permission.FILTER_EVENTS);
10382        }
10383
10384        final String annotation;
10385        if (reason == null) {
10386            annotation = "Input dispatching timed out";
10387        } else {
10388            annotation = "Input dispatching timed out (" + reason + ")";
10389        }
10390
10391        if (proc != null) {
10392            synchronized (this) {
10393                if (proc.debugging) {
10394                    return false;
10395                }
10396
10397                if (mDidDexOpt) {
10398                    // Give more time since we were dexopting.
10399                    mDidDexOpt = false;
10400                    return false;
10401                }
10402
10403                if (proc.instrumentationClass != null) {
10404                    Bundle info = new Bundle();
10405                    info.putString("shortMsg", "keyDispatchingTimedOut");
10406                    info.putString("longMsg", annotation);
10407                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10408                    return true;
10409                }
10410            }
10411            mHandler.post(new Runnable() {
10412                @Override
10413                public void run() {
10414                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10415                }
10416            });
10417        }
10418
10419        return true;
10420    }
10421
10422    public Bundle getAssistContextExtras(int requestType) {
10423        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10424                "getAssistContextExtras()");
10425        PendingAssistExtras pae;
10426        Bundle extras = new Bundle();
10427        synchronized (this) {
10428            ActivityRecord activity = getFocusedStack().mResumedActivity;
10429            if (activity == null) {
10430                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10431                return null;
10432            }
10433            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10434            if (activity.app == null || activity.app.thread == null) {
10435                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10436                return extras;
10437            }
10438            if (activity.app.pid == Binder.getCallingPid()) {
10439                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10440                return extras;
10441            }
10442            pae = new PendingAssistExtras(activity);
10443            try {
10444                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10445                        requestType);
10446                mPendingAssistExtras.add(pae);
10447                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10448            } catch (RemoteException e) {
10449                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10450                return extras;
10451            }
10452        }
10453        synchronized (pae) {
10454            while (!pae.haveResult) {
10455                try {
10456                    pae.wait();
10457                } catch (InterruptedException e) {
10458                }
10459            }
10460            if (pae.result != null) {
10461                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10462            }
10463        }
10464        synchronized (this) {
10465            mPendingAssistExtras.remove(pae);
10466            mHandler.removeCallbacks(pae);
10467        }
10468        return extras;
10469    }
10470
10471    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10472        PendingAssistExtras pae = (PendingAssistExtras)token;
10473        synchronized (pae) {
10474            pae.result = extras;
10475            pae.haveResult = true;
10476            pae.notifyAll();
10477        }
10478    }
10479
10480    public void registerProcessObserver(IProcessObserver observer) {
10481        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10482                "registerProcessObserver()");
10483        synchronized (this) {
10484            mProcessObservers.register(observer);
10485        }
10486    }
10487
10488    @Override
10489    public void unregisterProcessObserver(IProcessObserver observer) {
10490        synchronized (this) {
10491            mProcessObservers.unregister(observer);
10492        }
10493    }
10494
10495    @Override
10496    public boolean convertFromTranslucent(IBinder token) {
10497        final long origId = Binder.clearCallingIdentity();
10498        try {
10499            synchronized (this) {
10500                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10501                if (r == null) {
10502                    return false;
10503                }
10504                final boolean translucentChanged = r.changeWindowTranslucency(true);
10505                if (translucentChanged) {
10506                    r.task.stack.releaseBackgroundResources();
10507                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10508                }
10509                mWindowManager.setAppFullscreen(token, true);
10510                return translucentChanged;
10511            }
10512        } finally {
10513            Binder.restoreCallingIdentity(origId);
10514        }
10515    }
10516
10517    @Override
10518    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10519        final long origId = Binder.clearCallingIdentity();
10520        try {
10521            synchronized (this) {
10522                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10523                if (r == null) {
10524                    return false;
10525                }
10526                int index = r.task.mActivities.lastIndexOf(r);
10527                if (index > 0) {
10528                    ActivityRecord under = r.task.mActivities.get(index - 1);
10529                    under.returningOptions = options;
10530                }
10531                final boolean translucentChanged = r.changeWindowTranslucency(false);
10532                if (translucentChanged) {
10533                    r.task.stack.convertToTranslucent(r);
10534                }
10535                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10536                mWindowManager.setAppFullscreen(token, false);
10537                return translucentChanged;
10538            }
10539        } finally {
10540            Binder.restoreCallingIdentity(origId);
10541        }
10542    }
10543
10544    @Override
10545    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10546        final long origId = Binder.clearCallingIdentity();
10547        try {
10548            synchronized (this) {
10549                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10550                if (r != null) {
10551                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10552                }
10553            }
10554            return false;
10555        } finally {
10556            Binder.restoreCallingIdentity(origId);
10557        }
10558    }
10559
10560    @Override
10561    public boolean isBackgroundVisibleBehind(IBinder token) {
10562        final long origId = Binder.clearCallingIdentity();
10563        try {
10564            synchronized (this) {
10565                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10566                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10567                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10568                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10569                return visible;
10570            }
10571        } finally {
10572            Binder.restoreCallingIdentity(origId);
10573        }
10574    }
10575
10576    @Override
10577    public ActivityOptions getActivityOptions(IBinder token) {
10578        final long origId = Binder.clearCallingIdentity();
10579        try {
10580            synchronized (this) {
10581                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10582                if (r != null) {
10583                    final ActivityOptions activityOptions = r.pendingOptions;
10584                    r.pendingOptions = null;
10585                    return activityOptions;
10586                }
10587                return null;
10588            }
10589        } finally {
10590            Binder.restoreCallingIdentity(origId);
10591        }
10592    }
10593
10594    @Override
10595    public void setImmersive(IBinder token, boolean immersive) {
10596        synchronized(this) {
10597            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10598            if (r == null) {
10599                throw new IllegalArgumentException();
10600            }
10601            r.immersive = immersive;
10602
10603            // update associated state if we're frontmost
10604            if (r == mFocusedActivity) {
10605                if (DEBUG_IMMERSIVE) {
10606                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10607                }
10608                applyUpdateLockStateLocked(r);
10609            }
10610        }
10611    }
10612
10613    @Override
10614    public boolean isImmersive(IBinder token) {
10615        synchronized (this) {
10616            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10617            if (r == null) {
10618                throw new IllegalArgumentException();
10619            }
10620            return r.immersive;
10621        }
10622    }
10623
10624    public boolean isTopActivityImmersive() {
10625        enforceNotIsolatedCaller("startActivity");
10626        synchronized (this) {
10627            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10628            return (r != null) ? r.immersive : false;
10629        }
10630    }
10631
10632    @Override
10633    public boolean isTopOfTask(IBinder token) {
10634        synchronized (this) {
10635            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10636            if (r == null) {
10637                throw new IllegalArgumentException();
10638            }
10639            return r.task.getTopActivity() == r;
10640        }
10641    }
10642
10643    public final void enterSafeMode() {
10644        synchronized(this) {
10645            // It only makes sense to do this before the system is ready
10646            // and started launching other packages.
10647            if (!mSystemReady) {
10648                try {
10649                    AppGlobals.getPackageManager().enterSafeMode();
10650                } catch (RemoteException e) {
10651                }
10652            }
10653
10654            mSafeMode = true;
10655        }
10656    }
10657
10658    public final void showSafeModeOverlay() {
10659        View v = LayoutInflater.from(mContext).inflate(
10660                com.android.internal.R.layout.safe_mode, null);
10661        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10662        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10663        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10664        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10665        lp.gravity = Gravity.BOTTOM | Gravity.START;
10666        lp.format = v.getBackground().getOpacity();
10667        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10668                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10669        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10670        ((WindowManager)mContext.getSystemService(
10671                Context.WINDOW_SERVICE)).addView(v, lp);
10672    }
10673
10674    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10675        if (!(sender instanceof PendingIntentRecord)) {
10676            return;
10677        }
10678        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10679        synchronized (stats) {
10680            if (mBatteryStatsService.isOnBattery()) {
10681                mBatteryStatsService.enforceCallingPermission();
10682                PendingIntentRecord rec = (PendingIntentRecord)sender;
10683                int MY_UID = Binder.getCallingUid();
10684                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10685                BatteryStatsImpl.Uid.Pkg pkg =
10686                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10687                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10688                pkg.incWakeupsLocked();
10689            }
10690        }
10691    }
10692
10693    public boolean killPids(int[] pids, String pReason, boolean secure) {
10694        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10695            throw new SecurityException("killPids only available to the system");
10696        }
10697        String reason = (pReason == null) ? "Unknown" : pReason;
10698        // XXX Note: don't acquire main activity lock here, because the window
10699        // manager calls in with its locks held.
10700
10701        boolean killed = false;
10702        synchronized (mPidsSelfLocked) {
10703            int[] types = new int[pids.length];
10704            int worstType = 0;
10705            for (int i=0; i<pids.length; i++) {
10706                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10707                if (proc != null) {
10708                    int type = proc.setAdj;
10709                    types[i] = type;
10710                    if (type > worstType) {
10711                        worstType = type;
10712                    }
10713                }
10714            }
10715
10716            // If the worst oom_adj is somewhere in the cached proc LRU range,
10717            // then constrain it so we will kill all cached procs.
10718            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10719                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10720                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10721            }
10722
10723            // If this is not a secure call, don't let it kill processes that
10724            // are important.
10725            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10726                worstType = ProcessList.SERVICE_ADJ;
10727            }
10728
10729            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10730            for (int i=0; i<pids.length; i++) {
10731                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10732                if (proc == null) {
10733                    continue;
10734                }
10735                int adj = proc.setAdj;
10736                if (adj >= worstType && !proc.killedByAm) {
10737                    proc.kill(reason, true);
10738                    killed = true;
10739                }
10740            }
10741        }
10742        return killed;
10743    }
10744
10745    @Override
10746    public void killUid(int uid, String reason) {
10747        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10748            throw new SecurityException("killUid only available to the system");
10749        }
10750        synchronized (this) {
10751            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10752                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10753                    reason != null ? reason : "kill uid");
10754        }
10755    }
10756
10757    @Override
10758    public boolean killProcessesBelowForeground(String reason) {
10759        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10760            throw new SecurityException("killProcessesBelowForeground() only available to system");
10761        }
10762
10763        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10764    }
10765
10766    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10767        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10768            throw new SecurityException("killProcessesBelowAdj() only available to system");
10769        }
10770
10771        boolean killed = false;
10772        synchronized (mPidsSelfLocked) {
10773            final int size = mPidsSelfLocked.size();
10774            for (int i = 0; i < size; i++) {
10775                final int pid = mPidsSelfLocked.keyAt(i);
10776                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10777                if (proc == null) continue;
10778
10779                final int adj = proc.setAdj;
10780                if (adj > belowAdj && !proc.killedByAm) {
10781                    proc.kill(reason, true);
10782                    killed = true;
10783                }
10784            }
10785        }
10786        return killed;
10787    }
10788
10789    @Override
10790    public void hang(final IBinder who, boolean allowRestart) {
10791        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10792                != PackageManager.PERMISSION_GRANTED) {
10793            throw new SecurityException("Requires permission "
10794                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10795        }
10796
10797        final IBinder.DeathRecipient death = new DeathRecipient() {
10798            @Override
10799            public void binderDied() {
10800                synchronized (this) {
10801                    notifyAll();
10802                }
10803            }
10804        };
10805
10806        try {
10807            who.linkToDeath(death, 0);
10808        } catch (RemoteException e) {
10809            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10810            return;
10811        }
10812
10813        synchronized (this) {
10814            Watchdog.getInstance().setAllowRestart(allowRestart);
10815            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10816            synchronized (death) {
10817                while (who.isBinderAlive()) {
10818                    try {
10819                        death.wait();
10820                    } catch (InterruptedException e) {
10821                    }
10822                }
10823            }
10824            Watchdog.getInstance().setAllowRestart(true);
10825        }
10826    }
10827
10828    @Override
10829    public void restart() {
10830        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10831                != PackageManager.PERMISSION_GRANTED) {
10832            throw new SecurityException("Requires permission "
10833                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10834        }
10835
10836        Log.i(TAG, "Sending shutdown broadcast...");
10837
10838        BroadcastReceiver br = new BroadcastReceiver() {
10839            @Override public void onReceive(Context context, Intent intent) {
10840                // Now the broadcast is done, finish up the low-level shutdown.
10841                Log.i(TAG, "Shutting down activity manager...");
10842                shutdown(10000);
10843                Log.i(TAG, "Shutdown complete, restarting!");
10844                Process.killProcess(Process.myPid());
10845                System.exit(10);
10846            }
10847        };
10848
10849        // First send the high-level shut down broadcast.
10850        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10851        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10852        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10853        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10854        mContext.sendOrderedBroadcastAsUser(intent,
10855                UserHandle.ALL, null, br, mHandler, 0, null, null);
10856        */
10857        br.onReceive(mContext, intent);
10858    }
10859
10860    private long getLowRamTimeSinceIdle(long now) {
10861        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10862    }
10863
10864    @Override
10865    public void performIdleMaintenance() {
10866        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10867                != PackageManager.PERMISSION_GRANTED) {
10868            throw new SecurityException("Requires permission "
10869                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10870        }
10871
10872        synchronized (this) {
10873            final long now = SystemClock.uptimeMillis();
10874            final long timeSinceLastIdle = now - mLastIdleTime;
10875            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10876            mLastIdleTime = now;
10877            mLowRamTimeSinceLastIdle = 0;
10878            if (mLowRamStartTime != 0) {
10879                mLowRamStartTime = now;
10880            }
10881
10882            StringBuilder sb = new StringBuilder(128);
10883            sb.append("Idle maintenance over ");
10884            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10885            sb.append(" low RAM for ");
10886            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10887            Slog.i(TAG, sb.toString());
10888
10889            // If at least 1/3 of our time since the last idle period has been spent
10890            // with RAM low, then we want to kill processes.
10891            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10892
10893            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10894                ProcessRecord proc = mLruProcesses.get(i);
10895                if (proc.notCachedSinceIdle) {
10896                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10897                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10898                        if (doKilling && proc.initialIdlePss != 0
10899                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10900                            proc.kill("idle maint (pss " + proc.lastPss
10901                                    + " from " + proc.initialIdlePss + ")", true);
10902                        }
10903                    }
10904                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10905                    proc.notCachedSinceIdle = true;
10906                    proc.initialIdlePss = 0;
10907                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10908                            isSleeping(), now);
10909                }
10910            }
10911
10912            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10913            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10914        }
10915    }
10916
10917    private void retrieveSettings() {
10918        final ContentResolver resolver = mContext.getContentResolver();
10919        String debugApp = Settings.Global.getString(
10920            resolver, Settings.Global.DEBUG_APP);
10921        boolean waitForDebugger = Settings.Global.getInt(
10922            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10923        boolean alwaysFinishActivities = Settings.Global.getInt(
10924            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10925        boolean forceRtl = Settings.Global.getInt(
10926                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10927        // Transfer any global setting for forcing RTL layout, into a System Property
10928        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10929
10930        Configuration configuration = new Configuration();
10931        Settings.System.getConfiguration(resolver, configuration);
10932        if (forceRtl) {
10933            // This will take care of setting the correct layout direction flags
10934            configuration.setLayoutDirection(configuration.locale);
10935        }
10936
10937        synchronized (this) {
10938            mDebugApp = mOrigDebugApp = debugApp;
10939            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10940            mAlwaysFinishActivities = alwaysFinishActivities;
10941            // This happens before any activities are started, so we can
10942            // change mConfiguration in-place.
10943            updateConfigurationLocked(configuration, null, false, true);
10944            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10945        }
10946    }
10947
10948    /** Loads resources after the current configuration has been set. */
10949    private void loadResourcesOnSystemReady() {
10950        final Resources res = mContext.getResources();
10951        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10952        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10953        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10954    }
10955
10956    public boolean testIsSystemReady() {
10957        // no need to synchronize(this) just to read & return the value
10958        return mSystemReady;
10959    }
10960
10961    private static File getCalledPreBootReceiversFile() {
10962        File dataDir = Environment.getDataDirectory();
10963        File systemDir = new File(dataDir, "system");
10964        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10965        return fname;
10966    }
10967
10968    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10969        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10970        File file = getCalledPreBootReceiversFile();
10971        FileInputStream fis = null;
10972        try {
10973            fis = new FileInputStream(file);
10974            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10975            int fvers = dis.readInt();
10976            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10977                String vers = dis.readUTF();
10978                String codename = dis.readUTF();
10979                String build = dis.readUTF();
10980                if (android.os.Build.VERSION.RELEASE.equals(vers)
10981                        && android.os.Build.VERSION.CODENAME.equals(codename)
10982                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10983                    int num = dis.readInt();
10984                    while (num > 0) {
10985                        num--;
10986                        String pkg = dis.readUTF();
10987                        String cls = dis.readUTF();
10988                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10989                    }
10990                }
10991            }
10992        } catch (FileNotFoundException e) {
10993        } catch (IOException e) {
10994            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10995        } finally {
10996            if (fis != null) {
10997                try {
10998                    fis.close();
10999                } catch (IOException e) {
11000                }
11001            }
11002        }
11003        return lastDoneReceivers;
11004    }
11005
11006    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11007        File file = getCalledPreBootReceiversFile();
11008        FileOutputStream fos = null;
11009        DataOutputStream dos = null;
11010        try {
11011            fos = new FileOutputStream(file);
11012            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11013            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11014            dos.writeUTF(android.os.Build.VERSION.RELEASE);
11015            dos.writeUTF(android.os.Build.VERSION.CODENAME);
11016            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11017            dos.writeInt(list.size());
11018            for (int i=0; i<list.size(); i++) {
11019                dos.writeUTF(list.get(i).getPackageName());
11020                dos.writeUTF(list.get(i).getClassName());
11021            }
11022        } catch (IOException e) {
11023            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11024            file.delete();
11025        } finally {
11026            FileUtils.sync(fos);
11027            if (dos != null) {
11028                try {
11029                    dos.close();
11030                } catch (IOException e) {
11031                    // TODO Auto-generated catch block
11032                    e.printStackTrace();
11033                }
11034            }
11035        }
11036    }
11037
11038    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11039            ArrayList<ComponentName> doneReceivers, int userId) {
11040        boolean waitingUpdate = false;
11041        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11042        List<ResolveInfo> ris = null;
11043        try {
11044            ris = AppGlobals.getPackageManager().queryIntentReceivers(
11045                    intent, null, 0, userId);
11046        } catch (RemoteException e) {
11047        }
11048        if (ris != null) {
11049            for (int i=ris.size()-1; i>=0; i--) {
11050                if ((ris.get(i).activityInfo.applicationInfo.flags
11051                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
11052                    ris.remove(i);
11053                }
11054            }
11055            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11056
11057            // For User 0, load the version number. When delivering to a new user, deliver
11058            // to all receivers.
11059            if (userId == UserHandle.USER_OWNER) {
11060                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11061                for (int i=0; i<ris.size(); i++) {
11062                    ActivityInfo ai = ris.get(i).activityInfo;
11063                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
11064                    if (lastDoneReceivers.contains(comp)) {
11065                        // We already did the pre boot receiver for this app with the current
11066                        // platform version, so don't do it again...
11067                        ris.remove(i);
11068                        i--;
11069                        // ...however, do keep it as one that has been done, so we don't
11070                        // forget about it when rewriting the file of last done receivers.
11071                        doneReceivers.add(comp);
11072                    }
11073                }
11074            }
11075
11076            // If primary user, send broadcast to all available users, else just to userId
11077            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11078                    : new int[] { userId };
11079            for (int i = 0; i < ris.size(); i++) {
11080                ActivityInfo ai = ris.get(i).activityInfo;
11081                ComponentName comp = new ComponentName(ai.packageName, ai.name);
11082                doneReceivers.add(comp);
11083                intent.setComponent(comp);
11084                for (int j=0; j<users.length; j++) {
11085                    IIntentReceiver finisher = null;
11086                    // On last receiver and user, set up a completion callback
11087                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11088                        finisher = new IIntentReceiver.Stub() {
11089                            public void performReceive(Intent intent, int resultCode,
11090                                    String data, Bundle extras, boolean ordered,
11091                                    boolean sticky, int sendingUser) {
11092                                // The raw IIntentReceiver interface is called
11093                                // with the AM lock held, so redispatch to
11094                                // execute our code without the lock.
11095                                mHandler.post(onFinishCallback);
11096                            }
11097                        };
11098                    }
11099                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
11100                            + " for user " + users[j]);
11101                    broadcastIntentLocked(null, null, intent, null, finisher,
11102                            0, null, null, null, AppOpsManager.OP_NONE,
11103                            true, false, MY_PID, Process.SYSTEM_UID,
11104                            users[j]);
11105                    if (finisher != null) {
11106                        waitingUpdate = true;
11107                    }
11108                }
11109            }
11110        }
11111
11112        return waitingUpdate;
11113    }
11114
11115    public void systemReady(final Runnable goingCallback) {
11116        synchronized(this) {
11117            if (mSystemReady) {
11118                // If we're done calling all the receivers, run the next "boot phase" passed in
11119                // by the SystemServer
11120                if (goingCallback != null) {
11121                    goingCallback.run();
11122                }
11123                return;
11124            }
11125
11126            // Make sure we have the current profile info, since it is needed for
11127            // security checks.
11128            updateCurrentProfileIdsLocked();
11129
11130            if (mRecentTasks == null) {
11131                mRecentTasks = mTaskPersister.restoreTasksLocked();
11132                if (!mRecentTasks.isEmpty()) {
11133                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11134                }
11135                cleanupRecentTasksLocked(UserHandle.USER_ALL);
11136                mTaskPersister.startPersisting();
11137            }
11138
11139            // Check to see if there are any update receivers to run.
11140            if (!mDidUpdate) {
11141                if (mWaitingUpdate) {
11142                    return;
11143                }
11144                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11145                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11146                    public void run() {
11147                        synchronized (ActivityManagerService.this) {
11148                            mDidUpdate = true;
11149                        }
11150                        writeLastDonePreBootReceivers(doneReceivers);
11151                        showBootMessage(mContext.getText(
11152                                R.string.android_upgrading_complete),
11153                                false);
11154                        systemReady(goingCallback);
11155                    }
11156                }, doneReceivers, UserHandle.USER_OWNER);
11157
11158                if (mWaitingUpdate) {
11159                    return;
11160                }
11161                mDidUpdate = true;
11162            }
11163
11164            mAppOpsService.systemReady();
11165            mSystemReady = true;
11166        }
11167
11168        ArrayList<ProcessRecord> procsToKill = null;
11169        synchronized(mPidsSelfLocked) {
11170            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11171                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11172                if (!isAllowedWhileBooting(proc.info)){
11173                    if (procsToKill == null) {
11174                        procsToKill = new ArrayList<ProcessRecord>();
11175                    }
11176                    procsToKill.add(proc);
11177                }
11178            }
11179        }
11180
11181        synchronized(this) {
11182            if (procsToKill != null) {
11183                for (int i=procsToKill.size()-1; i>=0; i--) {
11184                    ProcessRecord proc = procsToKill.get(i);
11185                    Slog.i(TAG, "Removing system update proc: " + proc);
11186                    removeProcessLocked(proc, true, false, "system update done");
11187                }
11188            }
11189
11190            // Now that we have cleaned up any update processes, we
11191            // are ready to start launching real processes and know that
11192            // we won't trample on them any more.
11193            mProcessesReady = true;
11194        }
11195
11196        Slog.i(TAG, "System now ready");
11197        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11198            SystemClock.uptimeMillis());
11199
11200        synchronized(this) {
11201            // Make sure we have no pre-ready processes sitting around.
11202
11203            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11204                ResolveInfo ri = mContext.getPackageManager()
11205                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11206                                STOCK_PM_FLAGS);
11207                CharSequence errorMsg = null;
11208                if (ri != null) {
11209                    ActivityInfo ai = ri.activityInfo;
11210                    ApplicationInfo app = ai.applicationInfo;
11211                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11212                        mTopAction = Intent.ACTION_FACTORY_TEST;
11213                        mTopData = null;
11214                        mTopComponent = new ComponentName(app.packageName,
11215                                ai.name);
11216                    } else {
11217                        errorMsg = mContext.getResources().getText(
11218                                com.android.internal.R.string.factorytest_not_system);
11219                    }
11220                } else {
11221                    errorMsg = mContext.getResources().getText(
11222                            com.android.internal.R.string.factorytest_no_action);
11223                }
11224                if (errorMsg != null) {
11225                    mTopAction = null;
11226                    mTopData = null;
11227                    mTopComponent = null;
11228                    Message msg = Message.obtain();
11229                    msg.what = SHOW_FACTORY_ERROR_MSG;
11230                    msg.getData().putCharSequence("msg", errorMsg);
11231                    mHandler.sendMessage(msg);
11232                }
11233            }
11234        }
11235
11236        retrieveSettings();
11237        loadResourcesOnSystemReady();
11238
11239        synchronized (this) {
11240            readGrantedUriPermissionsLocked();
11241        }
11242
11243        if (goingCallback != null) goingCallback.run();
11244
11245        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11246                Integer.toString(mCurrentUserId), mCurrentUserId);
11247        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11248                Integer.toString(mCurrentUserId), mCurrentUserId);
11249        mSystemServiceManager.startUser(mCurrentUserId);
11250
11251        synchronized (this) {
11252            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11253                try {
11254                    List apps = AppGlobals.getPackageManager().
11255                        getPersistentApplications(STOCK_PM_FLAGS);
11256                    if (apps != null) {
11257                        int N = apps.size();
11258                        int i;
11259                        for (i=0; i<N; i++) {
11260                            ApplicationInfo info
11261                                = (ApplicationInfo)apps.get(i);
11262                            if (info != null &&
11263                                    !info.packageName.equals("android")) {
11264                                addAppLocked(info, false, null /* ABI override */);
11265                            }
11266                        }
11267                    }
11268                } catch (RemoteException ex) {
11269                    // pm is in same process, this will never happen.
11270                }
11271            }
11272
11273            // Start up initial activity.
11274            mBooting = true;
11275
11276            try {
11277                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11278                    Message msg = Message.obtain();
11279                    msg.what = SHOW_UID_ERROR_MSG;
11280                    mHandler.sendMessage(msg);
11281                }
11282            } catch (RemoteException e) {
11283            }
11284
11285            long ident = Binder.clearCallingIdentity();
11286            try {
11287                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11288                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11289                        | Intent.FLAG_RECEIVER_FOREGROUND);
11290                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11291                broadcastIntentLocked(null, null, intent,
11292                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11293                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11294                intent = new Intent(Intent.ACTION_USER_STARTING);
11295                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11296                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11297                broadcastIntentLocked(null, null, intent,
11298                        null, new IIntentReceiver.Stub() {
11299                            @Override
11300                            public void performReceive(Intent intent, int resultCode, String data,
11301                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11302                                    throws RemoteException {
11303                            }
11304                        }, 0, null, null,
11305                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11306                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11307            } catch (Throwable t) {
11308                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11309            } finally {
11310                Binder.restoreCallingIdentity(ident);
11311            }
11312            mStackSupervisor.resumeTopActivitiesLocked();
11313            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11314        }
11315    }
11316
11317    private boolean makeAppCrashingLocked(ProcessRecord app,
11318            String shortMsg, String longMsg, String stackTrace) {
11319        app.crashing = true;
11320        app.crashingReport = generateProcessError(app,
11321                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11322        startAppProblemLocked(app);
11323        app.stopFreezingAllLocked();
11324        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11325    }
11326
11327    private void makeAppNotRespondingLocked(ProcessRecord app,
11328            String activity, String shortMsg, String longMsg) {
11329        app.notResponding = true;
11330        app.notRespondingReport = generateProcessError(app,
11331                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11332                activity, shortMsg, longMsg, null);
11333        startAppProblemLocked(app);
11334        app.stopFreezingAllLocked();
11335    }
11336
11337    /**
11338     * Generate a process error record, suitable for attachment to a ProcessRecord.
11339     *
11340     * @param app The ProcessRecord in which the error occurred.
11341     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11342     *                      ActivityManager.AppErrorStateInfo
11343     * @param activity The activity associated with the crash, if known.
11344     * @param shortMsg Short message describing the crash.
11345     * @param longMsg Long message describing the crash.
11346     * @param stackTrace Full crash stack trace, may be null.
11347     *
11348     * @return Returns a fully-formed AppErrorStateInfo record.
11349     */
11350    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11351            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11352        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11353
11354        report.condition = condition;
11355        report.processName = app.processName;
11356        report.pid = app.pid;
11357        report.uid = app.info.uid;
11358        report.tag = activity;
11359        report.shortMsg = shortMsg;
11360        report.longMsg = longMsg;
11361        report.stackTrace = stackTrace;
11362
11363        return report;
11364    }
11365
11366    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11367        synchronized (this) {
11368            app.crashing = false;
11369            app.crashingReport = null;
11370            app.notResponding = false;
11371            app.notRespondingReport = null;
11372            if (app.anrDialog == fromDialog) {
11373                app.anrDialog = null;
11374            }
11375            if (app.waitDialog == fromDialog) {
11376                app.waitDialog = null;
11377            }
11378            if (app.pid > 0 && app.pid != MY_PID) {
11379                handleAppCrashLocked(app, null, null, null);
11380                app.kill("user request after error", true);
11381            }
11382        }
11383    }
11384
11385    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11386            String stackTrace) {
11387        long now = SystemClock.uptimeMillis();
11388
11389        Long crashTime;
11390        if (!app.isolated) {
11391            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11392        } else {
11393            crashTime = null;
11394        }
11395        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11396            // This process loses!
11397            Slog.w(TAG, "Process " + app.info.processName
11398                    + " has crashed too many times: killing!");
11399            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11400                    app.userId, app.info.processName, app.uid);
11401            mStackSupervisor.handleAppCrashLocked(app);
11402            if (!app.persistent) {
11403                // We don't want to start this process again until the user
11404                // explicitly does so...  but for persistent process, we really
11405                // need to keep it running.  If a persistent process is actually
11406                // repeatedly crashing, then badness for everyone.
11407                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11408                        app.info.processName);
11409                if (!app.isolated) {
11410                    // XXX We don't have a way to mark isolated processes
11411                    // as bad, since they don't have a peristent identity.
11412                    mBadProcesses.put(app.info.processName, app.uid,
11413                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11414                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11415                }
11416                app.bad = true;
11417                app.removed = true;
11418                // Don't let services in this process be restarted and potentially
11419                // annoy the user repeatedly.  Unless it is persistent, since those
11420                // processes run critical code.
11421                removeProcessLocked(app, false, false, "crash");
11422                mStackSupervisor.resumeTopActivitiesLocked();
11423                return false;
11424            }
11425            mStackSupervisor.resumeTopActivitiesLocked();
11426        } else {
11427            mStackSupervisor.finishTopRunningActivityLocked(app);
11428        }
11429
11430        // Bump up the crash count of any services currently running in the proc.
11431        for (int i=app.services.size()-1; i>=0; i--) {
11432            // Any services running in the application need to be placed
11433            // back in the pending list.
11434            ServiceRecord sr = app.services.valueAt(i);
11435            sr.crashCount++;
11436        }
11437
11438        // If the crashing process is what we consider to be the "home process" and it has been
11439        // replaced by a third-party app, clear the package preferred activities from packages
11440        // with a home activity running in the process to prevent a repeatedly crashing app
11441        // from blocking the user to manually clear the list.
11442        final ArrayList<ActivityRecord> activities = app.activities;
11443        if (app == mHomeProcess && activities.size() > 0
11444                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11445            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11446                final ActivityRecord r = activities.get(activityNdx);
11447                if (r.isHomeActivity()) {
11448                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11449                    try {
11450                        ActivityThread.getPackageManager()
11451                                .clearPackagePreferredActivities(r.packageName);
11452                    } catch (RemoteException c) {
11453                        // pm is in same process, this will never happen.
11454                    }
11455                }
11456            }
11457        }
11458
11459        if (!app.isolated) {
11460            // XXX Can't keep track of crash times for isolated processes,
11461            // because they don't have a perisistent identity.
11462            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11463        }
11464
11465        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11466        return true;
11467    }
11468
11469    void startAppProblemLocked(ProcessRecord app) {
11470        // If this app is not running under the current user, then we
11471        // can't give it a report button because that would require
11472        // launching the report UI under a different user.
11473        app.errorReportReceiver = null;
11474
11475        for (int userId : mCurrentProfileIds) {
11476            if (app.userId == userId) {
11477                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11478                        mContext, app.info.packageName, app.info.flags);
11479            }
11480        }
11481        skipCurrentReceiverLocked(app);
11482    }
11483
11484    void skipCurrentReceiverLocked(ProcessRecord app) {
11485        for (BroadcastQueue queue : mBroadcastQueues) {
11486            queue.skipCurrentReceiverLocked(app);
11487        }
11488    }
11489
11490    /**
11491     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11492     * The application process will exit immediately after this call returns.
11493     * @param app object of the crashing app, null for the system server
11494     * @param crashInfo describing the exception
11495     */
11496    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11497        ProcessRecord r = findAppProcess(app, "Crash");
11498        final String processName = app == null ? "system_server"
11499                : (r == null ? "unknown" : r.processName);
11500
11501        handleApplicationCrashInner("crash", r, processName, crashInfo);
11502    }
11503
11504    /* Native crash reporting uses this inner version because it needs to be somewhat
11505     * decoupled from the AM-managed cleanup lifecycle
11506     */
11507    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11508            ApplicationErrorReport.CrashInfo crashInfo) {
11509        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11510                UserHandle.getUserId(Binder.getCallingUid()), processName,
11511                r == null ? -1 : r.info.flags,
11512                crashInfo.exceptionClassName,
11513                crashInfo.exceptionMessage,
11514                crashInfo.throwFileName,
11515                crashInfo.throwLineNumber);
11516
11517        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11518
11519        crashApplication(r, crashInfo);
11520    }
11521
11522    public void handleApplicationStrictModeViolation(
11523            IBinder app,
11524            int violationMask,
11525            StrictMode.ViolationInfo info) {
11526        ProcessRecord r = findAppProcess(app, "StrictMode");
11527        if (r == null) {
11528            return;
11529        }
11530
11531        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11532            Integer stackFingerprint = info.hashCode();
11533            boolean logIt = true;
11534            synchronized (mAlreadyLoggedViolatedStacks) {
11535                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11536                    logIt = false;
11537                    // TODO: sub-sample into EventLog for these, with
11538                    // the info.durationMillis?  Then we'd get
11539                    // the relative pain numbers, without logging all
11540                    // the stack traces repeatedly.  We'd want to do
11541                    // likewise in the client code, which also does
11542                    // dup suppression, before the Binder call.
11543                } else {
11544                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11545                        mAlreadyLoggedViolatedStacks.clear();
11546                    }
11547                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11548                }
11549            }
11550            if (logIt) {
11551                logStrictModeViolationToDropBox(r, info);
11552            }
11553        }
11554
11555        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11556            AppErrorResult result = new AppErrorResult();
11557            synchronized (this) {
11558                final long origId = Binder.clearCallingIdentity();
11559
11560                Message msg = Message.obtain();
11561                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11562                HashMap<String, Object> data = new HashMap<String, Object>();
11563                data.put("result", result);
11564                data.put("app", r);
11565                data.put("violationMask", violationMask);
11566                data.put("info", info);
11567                msg.obj = data;
11568                mHandler.sendMessage(msg);
11569
11570                Binder.restoreCallingIdentity(origId);
11571            }
11572            int res = result.get();
11573            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11574        }
11575    }
11576
11577    // Depending on the policy in effect, there could be a bunch of
11578    // these in quick succession so we try to batch these together to
11579    // minimize disk writes, number of dropbox entries, and maximize
11580    // compression, by having more fewer, larger records.
11581    private void logStrictModeViolationToDropBox(
11582            ProcessRecord process,
11583            StrictMode.ViolationInfo info) {
11584        if (info == null) {
11585            return;
11586        }
11587        final boolean isSystemApp = process == null ||
11588                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11589                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11590        final String processName = process == null ? "unknown" : process.processName;
11591        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11592        final DropBoxManager dbox = (DropBoxManager)
11593                mContext.getSystemService(Context.DROPBOX_SERVICE);
11594
11595        // Exit early if the dropbox isn't configured to accept this report type.
11596        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11597
11598        boolean bufferWasEmpty;
11599        boolean needsFlush;
11600        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11601        synchronized (sb) {
11602            bufferWasEmpty = sb.length() == 0;
11603            appendDropBoxProcessHeaders(process, processName, sb);
11604            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11605            sb.append("System-App: ").append(isSystemApp).append("\n");
11606            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11607            if (info.violationNumThisLoop != 0) {
11608                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11609            }
11610            if (info.numAnimationsRunning != 0) {
11611                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11612            }
11613            if (info.broadcastIntentAction != null) {
11614                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11615            }
11616            if (info.durationMillis != -1) {
11617                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11618            }
11619            if (info.numInstances != -1) {
11620                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11621            }
11622            if (info.tags != null) {
11623                for (String tag : info.tags) {
11624                    sb.append("Span-Tag: ").append(tag).append("\n");
11625                }
11626            }
11627            sb.append("\n");
11628            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11629                sb.append(info.crashInfo.stackTrace);
11630            }
11631            sb.append("\n");
11632
11633            // Only buffer up to ~64k.  Various logging bits truncate
11634            // things at 128k.
11635            needsFlush = (sb.length() > 64 * 1024);
11636        }
11637
11638        // Flush immediately if the buffer's grown too large, or this
11639        // is a non-system app.  Non-system apps are isolated with a
11640        // different tag & policy and not batched.
11641        //
11642        // Batching is useful during internal testing with
11643        // StrictMode settings turned up high.  Without batching,
11644        // thousands of separate files could be created on boot.
11645        if (!isSystemApp || needsFlush) {
11646            new Thread("Error dump: " + dropboxTag) {
11647                @Override
11648                public void run() {
11649                    String report;
11650                    synchronized (sb) {
11651                        report = sb.toString();
11652                        sb.delete(0, sb.length());
11653                        sb.trimToSize();
11654                    }
11655                    if (report.length() != 0) {
11656                        dbox.addText(dropboxTag, report);
11657                    }
11658                }
11659            }.start();
11660            return;
11661        }
11662
11663        // System app batching:
11664        if (!bufferWasEmpty) {
11665            // An existing dropbox-writing thread is outstanding, so
11666            // we don't need to start it up.  The existing thread will
11667            // catch the buffer appends we just did.
11668            return;
11669        }
11670
11671        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11672        // (After this point, we shouldn't access AMS internal data structures.)
11673        new Thread("Error dump: " + dropboxTag) {
11674            @Override
11675            public void run() {
11676                // 5 second sleep to let stacks arrive and be batched together
11677                try {
11678                    Thread.sleep(5000);  // 5 seconds
11679                } catch (InterruptedException e) {}
11680
11681                String errorReport;
11682                synchronized (mStrictModeBuffer) {
11683                    errorReport = mStrictModeBuffer.toString();
11684                    if (errorReport.length() == 0) {
11685                        return;
11686                    }
11687                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11688                    mStrictModeBuffer.trimToSize();
11689                }
11690                dbox.addText(dropboxTag, errorReport);
11691            }
11692        }.start();
11693    }
11694
11695    /**
11696     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11697     * @param app object of the crashing app, null for the system server
11698     * @param tag reported by the caller
11699     * @param system whether this wtf is coming from the system
11700     * @param crashInfo describing the context of the error
11701     * @return true if the process should exit immediately (WTF is fatal)
11702     */
11703    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11704            final ApplicationErrorReport.CrashInfo crashInfo) {
11705        final ProcessRecord r = findAppProcess(app, "WTF");
11706        final String processName = app == null ? "system_server"
11707                : (r == null ? "unknown" : r.processName);
11708
11709        EventLog.writeEvent(EventLogTags.AM_WTF,
11710                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11711                processName,
11712                r == null ? -1 : r.info.flags,
11713                tag, crashInfo.exceptionMessage);
11714
11715        if (system) {
11716            // If this is coming from the system, we could very well have low-level
11717            // system locks held, so we want to do this all asynchronously.  And we
11718            // never want this to become fatal, so there is that too.
11719            mHandler.post(new Runnable() {
11720                @Override public void run() {
11721                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11722                            crashInfo);
11723                }
11724            });
11725            return false;
11726        }
11727
11728        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11729
11730        if (r != null && r.pid != Process.myPid() &&
11731                Settings.Global.getInt(mContext.getContentResolver(),
11732                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11733            crashApplication(r, crashInfo);
11734            return true;
11735        } else {
11736            return false;
11737        }
11738    }
11739
11740    /**
11741     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11742     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11743     */
11744    private ProcessRecord findAppProcess(IBinder app, String reason) {
11745        if (app == null) {
11746            return null;
11747        }
11748
11749        synchronized (this) {
11750            final int NP = mProcessNames.getMap().size();
11751            for (int ip=0; ip<NP; ip++) {
11752                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11753                final int NA = apps.size();
11754                for (int ia=0; ia<NA; ia++) {
11755                    ProcessRecord p = apps.valueAt(ia);
11756                    if (p.thread != null && p.thread.asBinder() == app) {
11757                        return p;
11758                    }
11759                }
11760            }
11761
11762            Slog.w(TAG, "Can't find mystery application for " + reason
11763                    + " from pid=" + Binder.getCallingPid()
11764                    + " uid=" + Binder.getCallingUid() + ": " + app);
11765            return null;
11766        }
11767    }
11768
11769    /**
11770     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11771     * to append various headers to the dropbox log text.
11772     */
11773    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11774            StringBuilder sb) {
11775        // Watchdog thread ends up invoking this function (with
11776        // a null ProcessRecord) to add the stack file to dropbox.
11777        // Do not acquire a lock on this (am) in such cases, as it
11778        // could cause a potential deadlock, if and when watchdog
11779        // is invoked due to unavailability of lock on am and it
11780        // would prevent watchdog from killing system_server.
11781        if (process == null) {
11782            sb.append("Process: ").append(processName).append("\n");
11783            return;
11784        }
11785        // Note: ProcessRecord 'process' is guarded by the service
11786        // instance.  (notably process.pkgList, which could otherwise change
11787        // concurrently during execution of this method)
11788        synchronized (this) {
11789            sb.append("Process: ").append(processName).append("\n");
11790            int flags = process.info.flags;
11791            IPackageManager pm = AppGlobals.getPackageManager();
11792            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11793            for (int ip=0; ip<process.pkgList.size(); ip++) {
11794                String pkg = process.pkgList.keyAt(ip);
11795                sb.append("Package: ").append(pkg);
11796                try {
11797                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11798                    if (pi != null) {
11799                        sb.append(" v").append(pi.versionCode);
11800                        if (pi.versionName != null) {
11801                            sb.append(" (").append(pi.versionName).append(")");
11802                        }
11803                    }
11804                } catch (RemoteException e) {
11805                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11806                }
11807                sb.append("\n");
11808            }
11809        }
11810    }
11811
11812    private static String processClass(ProcessRecord process) {
11813        if (process == null || process.pid == MY_PID) {
11814            return "system_server";
11815        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11816            return "system_app";
11817        } else {
11818            return "data_app";
11819        }
11820    }
11821
11822    /**
11823     * Write a description of an error (crash, WTF, ANR) to the drop box.
11824     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11825     * @param process which caused the error, null means the system server
11826     * @param activity which triggered the error, null if unknown
11827     * @param parent activity related to the error, null if unknown
11828     * @param subject line related to the error, null if absent
11829     * @param report in long form describing the error, null if absent
11830     * @param logFile to include in the report, null if none
11831     * @param crashInfo giving an application stack trace, null if absent
11832     */
11833    public void addErrorToDropBox(String eventType,
11834            ProcessRecord process, String processName, ActivityRecord activity,
11835            ActivityRecord parent, String subject,
11836            final String report, final File logFile,
11837            final ApplicationErrorReport.CrashInfo crashInfo) {
11838        // NOTE -- this must never acquire the ActivityManagerService lock,
11839        // otherwise the watchdog may be prevented from resetting the system.
11840
11841        final String dropboxTag = processClass(process) + "_" + eventType;
11842        final DropBoxManager dbox = (DropBoxManager)
11843                mContext.getSystemService(Context.DROPBOX_SERVICE);
11844
11845        // Exit early if the dropbox isn't configured to accept this report type.
11846        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11847
11848        final StringBuilder sb = new StringBuilder(1024);
11849        appendDropBoxProcessHeaders(process, processName, sb);
11850        if (activity != null) {
11851            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11852        }
11853        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11854            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11855        }
11856        if (parent != null && parent != activity) {
11857            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11858        }
11859        if (subject != null) {
11860            sb.append("Subject: ").append(subject).append("\n");
11861        }
11862        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11863        if (Debug.isDebuggerConnected()) {
11864            sb.append("Debugger: Connected\n");
11865        }
11866        sb.append("\n");
11867
11868        // Do the rest in a worker thread to avoid blocking the caller on I/O
11869        // (After this point, we shouldn't access AMS internal data structures.)
11870        Thread worker = new Thread("Error dump: " + dropboxTag) {
11871            @Override
11872            public void run() {
11873                if (report != null) {
11874                    sb.append(report);
11875                }
11876                if (logFile != null) {
11877                    try {
11878                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11879                                    "\n\n[[TRUNCATED]]"));
11880                    } catch (IOException e) {
11881                        Slog.e(TAG, "Error reading " + logFile, e);
11882                    }
11883                }
11884                if (crashInfo != null && crashInfo.stackTrace != null) {
11885                    sb.append(crashInfo.stackTrace);
11886                }
11887
11888                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11889                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11890                if (lines > 0) {
11891                    sb.append("\n");
11892
11893                    // Merge several logcat streams, and take the last N lines
11894                    InputStreamReader input = null;
11895                    try {
11896                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11897                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11898                                "-b", "crash",
11899                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11900
11901                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11902                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11903                        input = new InputStreamReader(logcat.getInputStream());
11904
11905                        int num;
11906                        char[] buf = new char[8192];
11907                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11908                    } catch (IOException e) {
11909                        Slog.e(TAG, "Error running logcat", e);
11910                    } finally {
11911                        if (input != null) try { input.close(); } catch (IOException e) {}
11912                    }
11913                }
11914
11915                dbox.addText(dropboxTag, sb.toString());
11916            }
11917        };
11918
11919        if (process == null) {
11920            // If process is null, we are being called from some internal code
11921            // and may be about to die -- run this synchronously.
11922            worker.run();
11923        } else {
11924            worker.start();
11925        }
11926    }
11927
11928    /**
11929     * Bring up the "unexpected error" dialog box for a crashing app.
11930     * Deal with edge cases (intercepts from instrumented applications,
11931     * ActivityController, error intent receivers, that sort of thing).
11932     * @param r the application crashing
11933     * @param crashInfo describing the failure
11934     */
11935    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11936        long timeMillis = System.currentTimeMillis();
11937        String shortMsg = crashInfo.exceptionClassName;
11938        String longMsg = crashInfo.exceptionMessage;
11939        String stackTrace = crashInfo.stackTrace;
11940        if (shortMsg != null && longMsg != null) {
11941            longMsg = shortMsg + ": " + longMsg;
11942        } else if (shortMsg != null) {
11943            longMsg = shortMsg;
11944        }
11945
11946        AppErrorResult result = new AppErrorResult();
11947        synchronized (this) {
11948            if (mController != null) {
11949                try {
11950                    String name = r != null ? r.processName : null;
11951                    int pid = r != null ? r.pid : Binder.getCallingPid();
11952                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11953                    if (!mController.appCrashed(name, pid,
11954                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11955                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11956                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11957                            Slog.w(TAG, "Skip killing native crashed app " + name
11958                                    + "(" + pid + ") during testing");
11959                        } else {
11960                            Slog.w(TAG, "Force-killing crashed app " + name
11961                                    + " at watcher's request");
11962                            if (r != null) {
11963                                r.kill("crash", true);
11964                            } else {
11965                                // Huh.
11966                                Process.killProcess(pid);
11967                                Process.killProcessGroup(uid, pid);
11968                            }
11969                        }
11970                        return;
11971                    }
11972                } catch (RemoteException e) {
11973                    mController = null;
11974                    Watchdog.getInstance().setActivityController(null);
11975                }
11976            }
11977
11978            final long origId = Binder.clearCallingIdentity();
11979
11980            // If this process is running instrumentation, finish it.
11981            if (r != null && r.instrumentationClass != null) {
11982                Slog.w(TAG, "Error in app " + r.processName
11983                      + " running instrumentation " + r.instrumentationClass + ":");
11984                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11985                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11986                Bundle info = new Bundle();
11987                info.putString("shortMsg", shortMsg);
11988                info.putString("longMsg", longMsg);
11989                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11990                Binder.restoreCallingIdentity(origId);
11991                return;
11992            }
11993
11994            // If we can't identify the process or it's already exceeded its crash quota,
11995            // quit right away without showing a crash dialog.
11996            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11997                Binder.restoreCallingIdentity(origId);
11998                return;
11999            }
12000
12001            Message msg = Message.obtain();
12002            msg.what = SHOW_ERROR_MSG;
12003            HashMap data = new HashMap();
12004            data.put("result", result);
12005            data.put("app", r);
12006            msg.obj = data;
12007            mHandler.sendMessage(msg);
12008
12009            Binder.restoreCallingIdentity(origId);
12010        }
12011
12012        int res = result.get();
12013
12014        Intent appErrorIntent = null;
12015        synchronized (this) {
12016            if (r != null && !r.isolated) {
12017                // XXX Can't keep track of crash time for isolated processes,
12018                // since they don't have a persistent identity.
12019                mProcessCrashTimes.put(r.info.processName, r.uid,
12020                        SystemClock.uptimeMillis());
12021            }
12022            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12023                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12024            }
12025        }
12026
12027        if (appErrorIntent != null) {
12028            try {
12029                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12030            } catch (ActivityNotFoundException e) {
12031                Slog.w(TAG, "bug report receiver dissappeared", e);
12032            }
12033        }
12034    }
12035
12036    Intent createAppErrorIntentLocked(ProcessRecord r,
12037            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12038        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12039        if (report == null) {
12040            return null;
12041        }
12042        Intent result = new Intent(Intent.ACTION_APP_ERROR);
12043        result.setComponent(r.errorReportReceiver);
12044        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12045        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12046        return result;
12047    }
12048
12049    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12050            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12051        if (r.errorReportReceiver == null) {
12052            return null;
12053        }
12054
12055        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12056            return null;
12057        }
12058
12059        ApplicationErrorReport report = new ApplicationErrorReport();
12060        report.packageName = r.info.packageName;
12061        report.installerPackageName = r.errorReportReceiver.getPackageName();
12062        report.processName = r.processName;
12063        report.time = timeMillis;
12064        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12065
12066        if (r.crashing || r.forceCrashReport) {
12067            report.type = ApplicationErrorReport.TYPE_CRASH;
12068            report.crashInfo = crashInfo;
12069        } else if (r.notResponding) {
12070            report.type = ApplicationErrorReport.TYPE_ANR;
12071            report.anrInfo = new ApplicationErrorReport.AnrInfo();
12072
12073            report.anrInfo.activity = r.notRespondingReport.tag;
12074            report.anrInfo.cause = r.notRespondingReport.shortMsg;
12075            report.anrInfo.info = r.notRespondingReport.longMsg;
12076        }
12077
12078        return report;
12079    }
12080
12081    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12082        enforceNotIsolatedCaller("getProcessesInErrorState");
12083        // assume our apps are happy - lazy create the list
12084        List<ActivityManager.ProcessErrorStateInfo> errList = null;
12085
12086        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12087                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12088        int userId = UserHandle.getUserId(Binder.getCallingUid());
12089
12090        synchronized (this) {
12091
12092            // iterate across all processes
12093            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12094                ProcessRecord app = mLruProcesses.get(i);
12095                if (!allUsers && app.userId != userId) {
12096                    continue;
12097                }
12098                if ((app.thread != null) && (app.crashing || app.notResponding)) {
12099                    // This one's in trouble, so we'll generate a report for it
12100                    // crashes are higher priority (in case there's a crash *and* an anr)
12101                    ActivityManager.ProcessErrorStateInfo report = null;
12102                    if (app.crashing) {
12103                        report = app.crashingReport;
12104                    } else if (app.notResponding) {
12105                        report = app.notRespondingReport;
12106                    }
12107
12108                    if (report != null) {
12109                        if (errList == null) {
12110                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12111                        }
12112                        errList.add(report);
12113                    } else {
12114                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
12115                                " crashing = " + app.crashing +
12116                                " notResponding = " + app.notResponding);
12117                    }
12118                }
12119            }
12120        }
12121
12122        return errList;
12123    }
12124
12125    static int procStateToImportance(int procState, int memAdj,
12126            ActivityManager.RunningAppProcessInfo currApp) {
12127        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12128        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12129            currApp.lru = memAdj;
12130        } else {
12131            currApp.lru = 0;
12132        }
12133        return imp;
12134    }
12135
12136    private void fillInProcMemInfo(ProcessRecord app,
12137            ActivityManager.RunningAppProcessInfo outInfo) {
12138        outInfo.pid = app.pid;
12139        outInfo.uid = app.info.uid;
12140        if (mHeavyWeightProcess == app) {
12141            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12142        }
12143        if (app.persistent) {
12144            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12145        }
12146        if (app.activities.size() > 0) {
12147            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12148        }
12149        outInfo.lastTrimLevel = app.trimMemoryLevel;
12150        int adj = app.curAdj;
12151        int procState = app.curProcState;
12152        outInfo.importance = procStateToImportance(procState, adj, outInfo);
12153        outInfo.importanceReasonCode = app.adjTypeCode;
12154        outInfo.processState = app.curProcState;
12155    }
12156
12157    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12158        enforceNotIsolatedCaller("getRunningAppProcesses");
12159        // Lazy instantiation of list
12160        List<ActivityManager.RunningAppProcessInfo> runList = null;
12161        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12162                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12163        int userId = UserHandle.getUserId(Binder.getCallingUid());
12164        synchronized (this) {
12165            // Iterate across all processes
12166            for (int i=mLruProcesses.size()-1; i>=0; i--) {
12167                ProcessRecord app = mLruProcesses.get(i);
12168                if (!allUsers && app.userId != userId) {
12169                    continue;
12170                }
12171                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12172                    // Generate process state info for running application
12173                    ActivityManager.RunningAppProcessInfo currApp =
12174                        new ActivityManager.RunningAppProcessInfo(app.processName,
12175                                app.pid, app.getPackageList());
12176                    fillInProcMemInfo(app, currApp);
12177                    if (app.adjSource instanceof ProcessRecord) {
12178                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12179                        currApp.importanceReasonImportance =
12180                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
12181                                        app.adjSourceProcState);
12182                    } else if (app.adjSource instanceof ActivityRecord) {
12183                        ActivityRecord r = (ActivityRecord)app.adjSource;
12184                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12185                    }
12186                    if (app.adjTarget instanceof ComponentName) {
12187                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12188                    }
12189                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12190                    //        + " lru=" + currApp.lru);
12191                    if (runList == null) {
12192                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
12193                    }
12194                    runList.add(currApp);
12195                }
12196            }
12197        }
12198        return runList;
12199    }
12200
12201    public List<ApplicationInfo> getRunningExternalApplications() {
12202        enforceNotIsolatedCaller("getRunningExternalApplications");
12203        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12204        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12205        if (runningApps != null && runningApps.size() > 0) {
12206            Set<String> extList = new HashSet<String>();
12207            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12208                if (app.pkgList != null) {
12209                    for (String pkg : app.pkgList) {
12210                        extList.add(pkg);
12211                    }
12212                }
12213            }
12214            IPackageManager pm = AppGlobals.getPackageManager();
12215            for (String pkg : extList) {
12216                try {
12217                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12218                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12219                        retList.add(info);
12220                    }
12221                } catch (RemoteException e) {
12222                }
12223            }
12224        }
12225        return retList;
12226    }
12227
12228    @Override
12229    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12230        enforceNotIsolatedCaller("getMyMemoryState");
12231        synchronized (this) {
12232            ProcessRecord proc;
12233            synchronized (mPidsSelfLocked) {
12234                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12235            }
12236            fillInProcMemInfo(proc, outInfo);
12237        }
12238    }
12239
12240    @Override
12241    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12242        if (checkCallingPermission(android.Manifest.permission.DUMP)
12243                != PackageManager.PERMISSION_GRANTED) {
12244            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12245                    + Binder.getCallingPid()
12246                    + ", uid=" + Binder.getCallingUid()
12247                    + " without permission "
12248                    + android.Manifest.permission.DUMP);
12249            return;
12250        }
12251
12252        boolean dumpAll = false;
12253        boolean dumpClient = false;
12254        String dumpPackage = null;
12255
12256        int opti = 0;
12257        while (opti < args.length) {
12258            String opt = args[opti];
12259            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12260                break;
12261            }
12262            opti++;
12263            if ("-a".equals(opt)) {
12264                dumpAll = true;
12265            } else if ("-c".equals(opt)) {
12266                dumpClient = true;
12267            } else if ("-h".equals(opt)) {
12268                pw.println("Activity manager dump options:");
12269                pw.println("  [-a] [-c] [-h] [cmd] ...");
12270                pw.println("  cmd may be one of:");
12271                pw.println("    a[ctivities]: activity stack state");
12272                pw.println("    r[recents]: recent activities state");
12273                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12274                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12275                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12276                pw.println("    o[om]: out of memory management");
12277                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12278                pw.println("    provider [COMP_SPEC]: provider client-side state");
12279                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12280                pw.println("    service [COMP_SPEC]: service client-side state");
12281                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12282                pw.println("    all: dump all activities");
12283                pw.println("    top: dump the top activity");
12284                pw.println("    write: write all pending state to storage");
12285                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12286                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12287                pw.println("    a partial substring in a component name, a");
12288                pw.println("    hex object identifier.");
12289                pw.println("  -a: include all available server state.");
12290                pw.println("  -c: include client state.");
12291                return;
12292            } else {
12293                pw.println("Unknown argument: " + opt + "; use -h for help");
12294            }
12295        }
12296
12297        long origId = Binder.clearCallingIdentity();
12298        boolean more = false;
12299        // Is the caller requesting to dump a particular piece of data?
12300        if (opti < args.length) {
12301            String cmd = args[opti];
12302            opti++;
12303            if ("activities".equals(cmd) || "a".equals(cmd)) {
12304                synchronized (this) {
12305                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12306                }
12307            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12308                synchronized (this) {
12309                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12310                }
12311            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12312                String[] newArgs;
12313                String name;
12314                if (opti >= args.length) {
12315                    name = null;
12316                    newArgs = EMPTY_STRING_ARRAY;
12317                } else {
12318                    name = args[opti];
12319                    opti++;
12320                    newArgs = new String[args.length - opti];
12321                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12322                            args.length - opti);
12323                }
12324                synchronized (this) {
12325                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12326                }
12327            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12328                String[] newArgs;
12329                String name;
12330                if (opti >= args.length) {
12331                    name = null;
12332                    newArgs = EMPTY_STRING_ARRAY;
12333                } else {
12334                    name = args[opti];
12335                    opti++;
12336                    newArgs = new String[args.length - opti];
12337                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12338                            args.length - opti);
12339                }
12340                synchronized (this) {
12341                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12342                }
12343            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12344                String[] newArgs;
12345                String name;
12346                if (opti >= args.length) {
12347                    name = null;
12348                    newArgs = EMPTY_STRING_ARRAY;
12349                } else {
12350                    name = args[opti];
12351                    opti++;
12352                    newArgs = new String[args.length - opti];
12353                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12354                            args.length - opti);
12355                }
12356                synchronized (this) {
12357                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12358                }
12359            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12360                synchronized (this) {
12361                    dumpOomLocked(fd, pw, args, opti, true);
12362                }
12363            } else if ("provider".equals(cmd)) {
12364                String[] newArgs;
12365                String name;
12366                if (opti >= args.length) {
12367                    name = null;
12368                    newArgs = EMPTY_STRING_ARRAY;
12369                } else {
12370                    name = args[opti];
12371                    opti++;
12372                    newArgs = new String[args.length - opti];
12373                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12374                }
12375                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12376                    pw.println("No providers match: " + name);
12377                    pw.println("Use -h for help.");
12378                }
12379            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12380                synchronized (this) {
12381                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12382                }
12383            } else if ("service".equals(cmd)) {
12384                String[] newArgs;
12385                String name;
12386                if (opti >= args.length) {
12387                    name = null;
12388                    newArgs = EMPTY_STRING_ARRAY;
12389                } else {
12390                    name = args[opti];
12391                    opti++;
12392                    newArgs = new String[args.length - opti];
12393                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12394                            args.length - opti);
12395                }
12396                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12397                    pw.println("No services match: " + name);
12398                    pw.println("Use -h for help.");
12399                }
12400            } else if ("package".equals(cmd)) {
12401                String[] newArgs;
12402                if (opti >= args.length) {
12403                    pw.println("package: no package name specified");
12404                    pw.println("Use -h for help.");
12405                } else {
12406                    dumpPackage = args[opti];
12407                    opti++;
12408                    newArgs = new String[args.length - opti];
12409                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12410                            args.length - opti);
12411                    args = newArgs;
12412                    opti = 0;
12413                    more = true;
12414                }
12415            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12416                synchronized (this) {
12417                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12418                }
12419            } else if ("write".equals(cmd)) {
12420                mTaskPersister.flush();
12421                pw.println("All tasks persisted.");
12422                return;
12423            } else {
12424                // Dumping a single activity?
12425                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12426                    pw.println("Bad activity command, or no activities match: " + cmd);
12427                    pw.println("Use -h for help.");
12428                }
12429            }
12430            if (!more) {
12431                Binder.restoreCallingIdentity(origId);
12432                return;
12433            }
12434        }
12435
12436        // No piece of data specified, dump everything.
12437        synchronized (this) {
12438            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12439            pw.println();
12440            if (dumpAll) {
12441                pw.println("-------------------------------------------------------------------------------");
12442            }
12443            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12444            pw.println();
12445            if (dumpAll) {
12446                pw.println("-------------------------------------------------------------------------------");
12447            }
12448            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12449            pw.println();
12450            if (dumpAll) {
12451                pw.println("-------------------------------------------------------------------------------");
12452            }
12453            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12454            pw.println();
12455            if (dumpAll) {
12456                pw.println("-------------------------------------------------------------------------------");
12457            }
12458            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12459            pw.println();
12460            if (dumpAll) {
12461                pw.println("-------------------------------------------------------------------------------");
12462            }
12463            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12464            pw.println();
12465            if (dumpAll) {
12466                pw.println("-------------------------------------------------------------------------------");
12467            }
12468            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12469        }
12470        Binder.restoreCallingIdentity(origId);
12471    }
12472
12473    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12474            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12475        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12476
12477        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12478                dumpPackage);
12479        boolean needSep = printedAnything;
12480
12481        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12482                dumpPackage, needSep, "  mFocusedActivity: ");
12483        if (printed) {
12484            printedAnything = true;
12485            needSep = false;
12486        }
12487
12488        if (dumpPackage == null) {
12489            if (needSep) {
12490                pw.println();
12491            }
12492            needSep = true;
12493            printedAnything = true;
12494            mStackSupervisor.dump(pw, "  ");
12495        }
12496
12497        if (!printedAnything) {
12498            pw.println("  (nothing)");
12499        }
12500    }
12501
12502    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12503            int opti, boolean dumpAll, String dumpPackage) {
12504        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12505
12506        boolean printedAnything = false;
12507
12508        if (mRecentTasks.size() > 0) {
12509            boolean printedHeader = false;
12510
12511            final int N = mRecentTasks.size();
12512            for (int i=0; i<N; i++) {
12513                TaskRecord tr = mRecentTasks.get(i);
12514                if (dumpPackage != null) {
12515                    if (tr.realActivity == null ||
12516                            !dumpPackage.equals(tr.realActivity)) {
12517                        continue;
12518                    }
12519                }
12520                if (!printedHeader) {
12521                    pw.println("  Recent tasks:");
12522                    printedHeader = true;
12523                    printedAnything = true;
12524                }
12525                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12526                        pw.println(tr);
12527                if (dumpAll) {
12528                    mRecentTasks.get(i).dump(pw, "    ");
12529                }
12530            }
12531        }
12532
12533        if (!printedAnything) {
12534            pw.println("  (nothing)");
12535        }
12536    }
12537
12538    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12539            int opti, boolean dumpAll, String dumpPackage) {
12540        boolean needSep = false;
12541        boolean printedAnything = false;
12542        int numPers = 0;
12543
12544        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12545
12546        if (dumpAll) {
12547            final int NP = mProcessNames.getMap().size();
12548            for (int ip=0; ip<NP; ip++) {
12549                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12550                final int NA = procs.size();
12551                for (int ia=0; ia<NA; ia++) {
12552                    ProcessRecord r = procs.valueAt(ia);
12553                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12554                        continue;
12555                    }
12556                    if (!needSep) {
12557                        pw.println("  All known processes:");
12558                        needSep = true;
12559                        printedAnything = true;
12560                    }
12561                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12562                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12563                        pw.print(" "); pw.println(r);
12564                    r.dump(pw, "    ");
12565                    if (r.persistent) {
12566                        numPers++;
12567                    }
12568                }
12569            }
12570        }
12571
12572        if (mIsolatedProcesses.size() > 0) {
12573            boolean printed = false;
12574            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12575                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12576                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12577                    continue;
12578                }
12579                if (!printed) {
12580                    if (needSep) {
12581                        pw.println();
12582                    }
12583                    pw.println("  Isolated process list (sorted by uid):");
12584                    printedAnything = true;
12585                    printed = true;
12586                    needSep = true;
12587                }
12588                pw.println(String.format("%sIsolated #%2d: %s",
12589                        "    ", i, r.toString()));
12590            }
12591        }
12592
12593        if (mLruProcesses.size() > 0) {
12594            if (needSep) {
12595                pw.println();
12596            }
12597            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12598                    pw.print(" total, non-act at ");
12599                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12600                    pw.print(", non-svc at ");
12601                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12602                    pw.println("):");
12603            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12604            needSep = true;
12605            printedAnything = true;
12606        }
12607
12608        if (dumpAll || dumpPackage != null) {
12609            synchronized (mPidsSelfLocked) {
12610                boolean printed = false;
12611                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12612                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12613                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12614                        continue;
12615                    }
12616                    if (!printed) {
12617                        if (needSep) pw.println();
12618                        needSep = true;
12619                        pw.println("  PID mappings:");
12620                        printed = true;
12621                        printedAnything = true;
12622                    }
12623                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12624                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12625                }
12626            }
12627        }
12628
12629        if (mForegroundProcesses.size() > 0) {
12630            synchronized (mPidsSelfLocked) {
12631                boolean printed = false;
12632                for (int i=0; i<mForegroundProcesses.size(); i++) {
12633                    ProcessRecord r = mPidsSelfLocked.get(
12634                            mForegroundProcesses.valueAt(i).pid);
12635                    if (dumpPackage != null && (r == null
12636                            || !r.pkgList.containsKey(dumpPackage))) {
12637                        continue;
12638                    }
12639                    if (!printed) {
12640                        if (needSep) pw.println();
12641                        needSep = true;
12642                        pw.println("  Foreground Processes:");
12643                        printed = true;
12644                        printedAnything = true;
12645                    }
12646                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12647                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12648                }
12649            }
12650        }
12651
12652        if (mPersistentStartingProcesses.size() > 0) {
12653            if (needSep) pw.println();
12654            needSep = true;
12655            printedAnything = true;
12656            pw.println("  Persisent processes that are starting:");
12657            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12658                    "Starting Norm", "Restarting PERS", dumpPackage);
12659        }
12660
12661        if (mRemovedProcesses.size() > 0) {
12662            if (needSep) pw.println();
12663            needSep = true;
12664            printedAnything = true;
12665            pw.println("  Processes that are being removed:");
12666            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12667                    "Removed Norm", "Removed PERS", dumpPackage);
12668        }
12669
12670        if (mProcessesOnHold.size() > 0) {
12671            if (needSep) pw.println();
12672            needSep = true;
12673            printedAnything = true;
12674            pw.println("  Processes that are on old until the system is ready:");
12675            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12676                    "OnHold Norm", "OnHold PERS", dumpPackage);
12677        }
12678
12679        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12680
12681        if (mProcessCrashTimes.getMap().size() > 0) {
12682            boolean printed = false;
12683            long now = SystemClock.uptimeMillis();
12684            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12685            final int NP = pmap.size();
12686            for (int ip=0; ip<NP; ip++) {
12687                String pname = pmap.keyAt(ip);
12688                SparseArray<Long> uids = pmap.valueAt(ip);
12689                final int N = uids.size();
12690                for (int i=0; i<N; i++) {
12691                    int puid = uids.keyAt(i);
12692                    ProcessRecord r = mProcessNames.get(pname, puid);
12693                    if (dumpPackage != null && (r == null
12694                            || !r.pkgList.containsKey(dumpPackage))) {
12695                        continue;
12696                    }
12697                    if (!printed) {
12698                        if (needSep) pw.println();
12699                        needSep = true;
12700                        pw.println("  Time since processes crashed:");
12701                        printed = true;
12702                        printedAnything = true;
12703                    }
12704                    pw.print("    Process "); pw.print(pname);
12705                            pw.print(" uid "); pw.print(puid);
12706                            pw.print(": last crashed ");
12707                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12708                            pw.println(" ago");
12709                }
12710            }
12711        }
12712
12713        if (mBadProcesses.getMap().size() > 0) {
12714            boolean printed = false;
12715            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12716            final int NP = pmap.size();
12717            for (int ip=0; ip<NP; ip++) {
12718                String pname = pmap.keyAt(ip);
12719                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12720                final int N = uids.size();
12721                for (int i=0; i<N; i++) {
12722                    int puid = uids.keyAt(i);
12723                    ProcessRecord r = mProcessNames.get(pname, puid);
12724                    if (dumpPackage != null && (r == null
12725                            || !r.pkgList.containsKey(dumpPackage))) {
12726                        continue;
12727                    }
12728                    if (!printed) {
12729                        if (needSep) pw.println();
12730                        needSep = true;
12731                        pw.println("  Bad processes:");
12732                        printedAnything = true;
12733                    }
12734                    BadProcessInfo info = uids.valueAt(i);
12735                    pw.print("    Bad process "); pw.print(pname);
12736                            pw.print(" uid "); pw.print(puid);
12737                            pw.print(": crashed at time "); pw.println(info.time);
12738                    if (info.shortMsg != null) {
12739                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12740                    }
12741                    if (info.longMsg != null) {
12742                        pw.print("      Long msg: "); pw.println(info.longMsg);
12743                    }
12744                    if (info.stack != null) {
12745                        pw.println("      Stack:");
12746                        int lastPos = 0;
12747                        for (int pos=0; pos<info.stack.length(); pos++) {
12748                            if (info.stack.charAt(pos) == '\n') {
12749                                pw.print("        ");
12750                                pw.write(info.stack, lastPos, pos-lastPos);
12751                                pw.println();
12752                                lastPos = pos+1;
12753                            }
12754                        }
12755                        if (lastPos < info.stack.length()) {
12756                            pw.print("        ");
12757                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12758                            pw.println();
12759                        }
12760                    }
12761                }
12762            }
12763        }
12764
12765        if (dumpPackage == null) {
12766            pw.println();
12767            needSep = false;
12768            pw.println("  mStartedUsers:");
12769            for (int i=0; i<mStartedUsers.size(); i++) {
12770                UserStartedState uss = mStartedUsers.valueAt(i);
12771                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12772                        pw.print(": "); uss.dump("", pw);
12773            }
12774            pw.print("  mStartedUserArray: [");
12775            for (int i=0; i<mStartedUserArray.length; i++) {
12776                if (i > 0) pw.print(", ");
12777                pw.print(mStartedUserArray[i]);
12778            }
12779            pw.println("]");
12780            pw.print("  mUserLru: [");
12781            for (int i=0; i<mUserLru.size(); i++) {
12782                if (i > 0) pw.print(", ");
12783                pw.print(mUserLru.get(i));
12784            }
12785            pw.println("]");
12786            if (dumpAll) {
12787                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12788            }
12789            synchronized (mUserProfileGroupIdsSelfLocked) {
12790                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12791                    pw.println("  mUserProfileGroupIds:");
12792                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12793                        pw.print("    User #");
12794                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12795                        pw.print(" -> profile #");
12796                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12797                    }
12798                }
12799            }
12800        }
12801        if (mHomeProcess != null && (dumpPackage == null
12802                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12803            if (needSep) {
12804                pw.println();
12805                needSep = false;
12806            }
12807            pw.println("  mHomeProcess: " + mHomeProcess);
12808        }
12809        if (mPreviousProcess != null && (dumpPackage == null
12810                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12811            if (needSep) {
12812                pw.println();
12813                needSep = false;
12814            }
12815            pw.println("  mPreviousProcess: " + mPreviousProcess);
12816        }
12817        if (dumpAll) {
12818            StringBuilder sb = new StringBuilder(128);
12819            sb.append("  mPreviousProcessVisibleTime: ");
12820            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12821            pw.println(sb);
12822        }
12823        if (mHeavyWeightProcess != null && (dumpPackage == null
12824                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12825            if (needSep) {
12826                pw.println();
12827                needSep = false;
12828            }
12829            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12830        }
12831        if (dumpPackage == null) {
12832            pw.println("  mConfiguration: " + mConfiguration);
12833        }
12834        if (dumpAll) {
12835            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12836            if (mCompatModePackages.getPackages().size() > 0) {
12837                boolean printed = false;
12838                for (Map.Entry<String, Integer> entry
12839                        : mCompatModePackages.getPackages().entrySet()) {
12840                    String pkg = entry.getKey();
12841                    int mode = entry.getValue();
12842                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12843                        continue;
12844                    }
12845                    if (!printed) {
12846                        pw.println("  mScreenCompatPackages:");
12847                        printed = true;
12848                    }
12849                    pw.print("    "); pw.print(pkg); pw.print(": ");
12850                            pw.print(mode); pw.println();
12851                }
12852            }
12853        }
12854        if (dumpPackage == null) {
12855            if (mSleeping || mWentToSleep || mLockScreenShown) {
12856                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12857                        + " mLockScreenShown " + mLockScreenShown);
12858            }
12859            if (mShuttingDown || mRunningVoice) {
12860                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12861            }
12862        }
12863        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12864                || mOrigWaitForDebugger) {
12865            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12866                    || dumpPackage.equals(mOrigDebugApp)) {
12867                if (needSep) {
12868                    pw.println();
12869                    needSep = false;
12870                }
12871                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12872                        + " mDebugTransient=" + mDebugTransient
12873                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12874            }
12875        }
12876        if (mOpenGlTraceApp != null) {
12877            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12878                if (needSep) {
12879                    pw.println();
12880                    needSep = false;
12881                }
12882                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12883            }
12884        }
12885        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12886                || mProfileFd != null) {
12887            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12888                if (needSep) {
12889                    pw.println();
12890                    needSep = false;
12891                }
12892                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12893                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12894                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12895                        + mAutoStopProfiler);
12896                pw.println("  mProfileType=" + mProfileType);
12897            }
12898        }
12899        if (dumpPackage == null) {
12900            if (mAlwaysFinishActivities || mController != null) {
12901                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12902                        + " mController=" + mController);
12903            }
12904            if (dumpAll) {
12905                pw.println("  Total persistent processes: " + numPers);
12906                pw.println("  mProcessesReady=" + mProcessesReady
12907                        + " mSystemReady=" + mSystemReady);
12908                pw.println("  mBooting=" + mBooting
12909                        + " mBooted=" + mBooted
12910                        + " mFactoryTest=" + mFactoryTest);
12911                pw.print("  mLastPowerCheckRealtime=");
12912                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12913                        pw.println("");
12914                pw.print("  mLastPowerCheckUptime=");
12915                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12916                        pw.println("");
12917                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12918                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12919                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12920                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12921                        + " (" + mLruProcesses.size() + " total)"
12922                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12923                        + " mNumServiceProcs=" + mNumServiceProcs
12924                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12925                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12926                        + " mLastMemoryLevel" + mLastMemoryLevel
12927                        + " mLastNumProcesses" + mLastNumProcesses);
12928                long now = SystemClock.uptimeMillis();
12929                pw.print("  mLastIdleTime=");
12930                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12931                        pw.print(" mLowRamSinceLastIdle=");
12932                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12933                        pw.println();
12934            }
12935        }
12936
12937        if (!printedAnything) {
12938            pw.println("  (nothing)");
12939        }
12940    }
12941
12942    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12943            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12944        if (mProcessesToGc.size() > 0) {
12945            boolean printed = false;
12946            long now = SystemClock.uptimeMillis();
12947            for (int i=0; i<mProcessesToGc.size(); i++) {
12948                ProcessRecord proc = mProcessesToGc.get(i);
12949                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12950                    continue;
12951                }
12952                if (!printed) {
12953                    if (needSep) pw.println();
12954                    needSep = true;
12955                    pw.println("  Processes that are waiting to GC:");
12956                    printed = true;
12957                }
12958                pw.print("    Process "); pw.println(proc);
12959                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12960                        pw.print(", last gced=");
12961                        pw.print(now-proc.lastRequestedGc);
12962                        pw.print(" ms ago, last lowMem=");
12963                        pw.print(now-proc.lastLowMemory);
12964                        pw.println(" ms ago");
12965
12966            }
12967        }
12968        return needSep;
12969    }
12970
12971    void printOomLevel(PrintWriter pw, String name, int adj) {
12972        pw.print("    ");
12973        if (adj >= 0) {
12974            pw.print(' ');
12975            if (adj < 10) pw.print(' ');
12976        } else {
12977            if (adj > -10) pw.print(' ');
12978        }
12979        pw.print(adj);
12980        pw.print(": ");
12981        pw.print(name);
12982        pw.print(" (");
12983        pw.print(mProcessList.getMemLevel(adj)/1024);
12984        pw.println(" kB)");
12985    }
12986
12987    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12988            int opti, boolean dumpAll) {
12989        boolean needSep = false;
12990
12991        if (mLruProcesses.size() > 0) {
12992            if (needSep) pw.println();
12993            needSep = true;
12994            pw.println("  OOM levels:");
12995            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12996            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12997            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12998            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12999            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13000            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13001            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13002            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13003            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13004            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13005            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13006            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13007            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13008
13009            if (needSep) pw.println();
13010            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
13011                    pw.print(" total, non-act at ");
13012                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13013                    pw.print(", non-svc at ");
13014                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13015                    pw.println("):");
13016            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
13017            needSep = true;
13018        }
13019
13020        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13021
13022        pw.println();
13023        pw.println("  mHomeProcess: " + mHomeProcess);
13024        pw.println("  mPreviousProcess: " + mPreviousProcess);
13025        if (mHeavyWeightProcess != null) {
13026            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
13027        }
13028
13029        return true;
13030    }
13031
13032    /**
13033     * There are three ways to call this:
13034     *  - no provider specified: dump all the providers
13035     *  - a flattened component name that matched an existing provider was specified as the
13036     *    first arg: dump that one provider
13037     *  - the first arg isn't the flattened component name of an existing provider:
13038     *    dump all providers whose component contains the first arg as a substring
13039     */
13040    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13041            int opti, boolean dumpAll) {
13042        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13043    }
13044
13045    static class ItemMatcher {
13046        ArrayList<ComponentName> components;
13047        ArrayList<String> strings;
13048        ArrayList<Integer> objects;
13049        boolean all;
13050
13051        ItemMatcher() {
13052            all = true;
13053        }
13054
13055        void build(String name) {
13056            ComponentName componentName = ComponentName.unflattenFromString(name);
13057            if (componentName != null) {
13058                if (components == null) {
13059                    components = new ArrayList<ComponentName>();
13060                }
13061                components.add(componentName);
13062                all = false;
13063            } else {
13064                int objectId = 0;
13065                // Not a '/' separated full component name; maybe an object ID?
13066                try {
13067                    objectId = Integer.parseInt(name, 16);
13068                    if (objects == null) {
13069                        objects = new ArrayList<Integer>();
13070                    }
13071                    objects.add(objectId);
13072                    all = false;
13073                } catch (RuntimeException e) {
13074                    // Not an integer; just do string match.
13075                    if (strings == null) {
13076                        strings = new ArrayList<String>();
13077                    }
13078                    strings.add(name);
13079                    all = false;
13080                }
13081            }
13082        }
13083
13084        int build(String[] args, int opti) {
13085            for (; opti<args.length; opti++) {
13086                String name = args[opti];
13087                if ("--".equals(name)) {
13088                    return opti+1;
13089                }
13090                build(name);
13091            }
13092            return opti;
13093        }
13094
13095        boolean match(Object object, ComponentName comp) {
13096            if (all) {
13097                return true;
13098            }
13099            if (components != null) {
13100                for (int i=0; i<components.size(); i++) {
13101                    if (components.get(i).equals(comp)) {
13102                        return true;
13103                    }
13104                }
13105            }
13106            if (objects != null) {
13107                for (int i=0; i<objects.size(); i++) {
13108                    if (System.identityHashCode(object) == objects.get(i)) {
13109                        return true;
13110                    }
13111                }
13112            }
13113            if (strings != null) {
13114                String flat = comp.flattenToString();
13115                for (int i=0; i<strings.size(); i++) {
13116                    if (flat.contains(strings.get(i))) {
13117                        return true;
13118                    }
13119                }
13120            }
13121            return false;
13122        }
13123    }
13124
13125    /**
13126     * There are three things that cmd can be:
13127     *  - a flattened component name that matches an existing activity
13128     *  - the cmd arg isn't the flattened component name of an existing activity:
13129     *    dump all activity whose component contains the cmd as a substring
13130     *  - A hex number of the ActivityRecord object instance.
13131     */
13132    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13133            int opti, boolean dumpAll) {
13134        ArrayList<ActivityRecord> activities;
13135
13136        synchronized (this) {
13137            activities = mStackSupervisor.getDumpActivitiesLocked(name);
13138        }
13139
13140        if (activities.size() <= 0) {
13141            return false;
13142        }
13143
13144        String[] newArgs = new String[args.length - opti];
13145        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13146
13147        TaskRecord lastTask = null;
13148        boolean needSep = false;
13149        for (int i=activities.size()-1; i>=0; i--) {
13150            ActivityRecord r = activities.get(i);
13151            if (needSep) {
13152                pw.println();
13153            }
13154            needSep = true;
13155            synchronized (this) {
13156                if (lastTask != r.task) {
13157                    lastTask = r.task;
13158                    pw.print("TASK "); pw.print(lastTask.affinity);
13159                            pw.print(" id="); pw.println(lastTask.taskId);
13160                    if (dumpAll) {
13161                        lastTask.dump(pw, "  ");
13162                    }
13163                }
13164            }
13165            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
13166        }
13167        return true;
13168    }
13169
13170    /**
13171     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13172     * there is a thread associated with the activity.
13173     */
13174    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13175            final ActivityRecord r, String[] args, boolean dumpAll) {
13176        String innerPrefix = prefix + "  ";
13177        synchronized (this) {
13178            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13179                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13180                    pw.print(" pid=");
13181                    if (r.app != null) pw.println(r.app.pid);
13182                    else pw.println("(not running)");
13183            if (dumpAll) {
13184                r.dump(pw, innerPrefix);
13185            }
13186        }
13187        if (r.app != null && r.app.thread != null) {
13188            // flush anything that is already in the PrintWriter since the thread is going
13189            // to write to the file descriptor directly
13190            pw.flush();
13191            try {
13192                TransferPipe tp = new TransferPipe();
13193                try {
13194                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13195                            r.appToken, innerPrefix, args);
13196                    tp.go(fd);
13197                } finally {
13198                    tp.kill();
13199                }
13200            } catch (IOException e) {
13201                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13202            } catch (RemoteException e) {
13203                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13204            }
13205        }
13206    }
13207
13208    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13209            int opti, boolean dumpAll, String dumpPackage) {
13210        boolean needSep = false;
13211        boolean onlyHistory = false;
13212        boolean printedAnything = false;
13213
13214        if ("history".equals(dumpPackage)) {
13215            if (opti < args.length && "-s".equals(args[opti])) {
13216                dumpAll = false;
13217            }
13218            onlyHistory = true;
13219            dumpPackage = null;
13220        }
13221
13222        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13223        if (!onlyHistory && dumpAll) {
13224            if (mRegisteredReceivers.size() > 0) {
13225                boolean printed = false;
13226                Iterator it = mRegisteredReceivers.values().iterator();
13227                while (it.hasNext()) {
13228                    ReceiverList r = (ReceiverList)it.next();
13229                    if (dumpPackage != null && (r.app == null ||
13230                            !dumpPackage.equals(r.app.info.packageName))) {
13231                        continue;
13232                    }
13233                    if (!printed) {
13234                        pw.println("  Registered Receivers:");
13235                        needSep = true;
13236                        printed = true;
13237                        printedAnything = true;
13238                    }
13239                    pw.print("  * "); pw.println(r);
13240                    r.dump(pw, "    ");
13241                }
13242            }
13243
13244            if (mReceiverResolver.dump(pw, needSep ?
13245                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13246                    "    ", dumpPackage, false)) {
13247                needSep = true;
13248                printedAnything = true;
13249            }
13250        }
13251
13252        for (BroadcastQueue q : mBroadcastQueues) {
13253            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13254            printedAnything |= needSep;
13255        }
13256
13257        needSep = true;
13258
13259        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13260            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13261                if (needSep) {
13262                    pw.println();
13263                }
13264                needSep = true;
13265                printedAnything = true;
13266                pw.print("  Sticky broadcasts for user ");
13267                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13268                StringBuilder sb = new StringBuilder(128);
13269                for (Map.Entry<String, ArrayList<Intent>> ent
13270                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13271                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13272                    if (dumpAll) {
13273                        pw.println(":");
13274                        ArrayList<Intent> intents = ent.getValue();
13275                        final int N = intents.size();
13276                        for (int i=0; i<N; i++) {
13277                            sb.setLength(0);
13278                            sb.append("    Intent: ");
13279                            intents.get(i).toShortString(sb, false, true, false, false);
13280                            pw.println(sb.toString());
13281                            Bundle bundle = intents.get(i).getExtras();
13282                            if (bundle != null) {
13283                                pw.print("      ");
13284                                pw.println(bundle.toString());
13285                            }
13286                        }
13287                    } else {
13288                        pw.println("");
13289                    }
13290                }
13291            }
13292        }
13293
13294        if (!onlyHistory && dumpAll) {
13295            pw.println();
13296            for (BroadcastQueue queue : mBroadcastQueues) {
13297                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13298                        + queue.mBroadcastsScheduled);
13299            }
13300            pw.println("  mHandler:");
13301            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13302            needSep = true;
13303            printedAnything = true;
13304        }
13305
13306        if (!printedAnything) {
13307            pw.println("  (nothing)");
13308        }
13309    }
13310
13311    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13312            int opti, boolean dumpAll, String dumpPackage) {
13313        boolean needSep;
13314        boolean printedAnything = false;
13315
13316        ItemMatcher matcher = new ItemMatcher();
13317        matcher.build(args, opti);
13318
13319        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13320
13321        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13322        printedAnything |= needSep;
13323
13324        if (mLaunchingProviders.size() > 0) {
13325            boolean printed = false;
13326            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13327                ContentProviderRecord r = mLaunchingProviders.get(i);
13328                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13329                    continue;
13330                }
13331                if (!printed) {
13332                    if (needSep) pw.println();
13333                    needSep = true;
13334                    pw.println("  Launching content providers:");
13335                    printed = true;
13336                    printedAnything = true;
13337                }
13338                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13339                        pw.println(r);
13340            }
13341        }
13342
13343        if (mGrantedUriPermissions.size() > 0) {
13344            boolean printed = false;
13345            int dumpUid = -2;
13346            if (dumpPackage != null) {
13347                try {
13348                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13349                } catch (NameNotFoundException e) {
13350                    dumpUid = -1;
13351                }
13352            }
13353            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13354                int uid = mGrantedUriPermissions.keyAt(i);
13355                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13356                    continue;
13357                }
13358                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13359                if (!printed) {
13360                    if (needSep) pw.println();
13361                    needSep = true;
13362                    pw.println("  Granted Uri Permissions:");
13363                    printed = true;
13364                    printedAnything = true;
13365                }
13366                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13367                for (UriPermission perm : perms.values()) {
13368                    pw.print("    "); pw.println(perm);
13369                    if (dumpAll) {
13370                        perm.dump(pw, "      ");
13371                    }
13372                }
13373            }
13374        }
13375
13376        if (!printedAnything) {
13377            pw.println("  (nothing)");
13378        }
13379    }
13380
13381    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13382            int opti, boolean dumpAll, String dumpPackage) {
13383        boolean printed = false;
13384
13385        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13386
13387        if (mIntentSenderRecords.size() > 0) {
13388            Iterator<WeakReference<PendingIntentRecord>> it
13389                    = mIntentSenderRecords.values().iterator();
13390            while (it.hasNext()) {
13391                WeakReference<PendingIntentRecord> ref = it.next();
13392                PendingIntentRecord rec = ref != null ? ref.get(): null;
13393                if (dumpPackage != null && (rec == null
13394                        || !dumpPackage.equals(rec.key.packageName))) {
13395                    continue;
13396                }
13397                printed = true;
13398                if (rec != null) {
13399                    pw.print("  * "); pw.println(rec);
13400                    if (dumpAll) {
13401                        rec.dump(pw, "    ");
13402                    }
13403                } else {
13404                    pw.print("  * "); pw.println(ref);
13405                }
13406            }
13407        }
13408
13409        if (!printed) {
13410            pw.println("  (nothing)");
13411        }
13412    }
13413
13414    private static final int dumpProcessList(PrintWriter pw,
13415            ActivityManagerService service, List list,
13416            String prefix, String normalLabel, String persistentLabel,
13417            String dumpPackage) {
13418        int numPers = 0;
13419        final int N = list.size()-1;
13420        for (int i=N; i>=0; i--) {
13421            ProcessRecord r = (ProcessRecord)list.get(i);
13422            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13423                continue;
13424            }
13425            pw.println(String.format("%s%s #%2d: %s",
13426                    prefix, (r.persistent ? persistentLabel : normalLabel),
13427                    i, r.toString()));
13428            if (r.persistent) {
13429                numPers++;
13430            }
13431        }
13432        return numPers;
13433    }
13434
13435    private static final boolean dumpProcessOomList(PrintWriter pw,
13436            ActivityManagerService service, List<ProcessRecord> origList,
13437            String prefix, String normalLabel, String persistentLabel,
13438            boolean inclDetails, String dumpPackage) {
13439
13440        ArrayList<Pair<ProcessRecord, Integer>> list
13441                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13442        for (int i=0; i<origList.size(); i++) {
13443            ProcessRecord r = origList.get(i);
13444            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13445                continue;
13446            }
13447            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13448        }
13449
13450        if (list.size() <= 0) {
13451            return false;
13452        }
13453
13454        Comparator<Pair<ProcessRecord, Integer>> comparator
13455                = new Comparator<Pair<ProcessRecord, Integer>>() {
13456            @Override
13457            public int compare(Pair<ProcessRecord, Integer> object1,
13458                    Pair<ProcessRecord, Integer> object2) {
13459                if (object1.first.setAdj != object2.first.setAdj) {
13460                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13461                }
13462                if (object1.second.intValue() != object2.second.intValue()) {
13463                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13464                }
13465                return 0;
13466            }
13467        };
13468
13469        Collections.sort(list, comparator);
13470
13471        final long curRealtime = SystemClock.elapsedRealtime();
13472        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13473        final long curUptime = SystemClock.uptimeMillis();
13474        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13475
13476        for (int i=list.size()-1; i>=0; i--) {
13477            ProcessRecord r = list.get(i).first;
13478            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13479            char schedGroup;
13480            switch (r.setSchedGroup) {
13481                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13482                    schedGroup = 'B';
13483                    break;
13484                case Process.THREAD_GROUP_DEFAULT:
13485                    schedGroup = 'F';
13486                    break;
13487                default:
13488                    schedGroup = '?';
13489                    break;
13490            }
13491            char foreground;
13492            if (r.foregroundActivities) {
13493                foreground = 'A';
13494            } else if (r.foregroundServices) {
13495                foreground = 'S';
13496            } else {
13497                foreground = ' ';
13498            }
13499            String procState = ProcessList.makeProcStateString(r.curProcState);
13500            pw.print(prefix);
13501            pw.print(r.persistent ? persistentLabel : normalLabel);
13502            pw.print(" #");
13503            int num = (origList.size()-1)-list.get(i).second;
13504            if (num < 10) pw.print(' ');
13505            pw.print(num);
13506            pw.print(": ");
13507            pw.print(oomAdj);
13508            pw.print(' ');
13509            pw.print(schedGroup);
13510            pw.print('/');
13511            pw.print(foreground);
13512            pw.print('/');
13513            pw.print(procState);
13514            pw.print(" trm:");
13515            if (r.trimMemoryLevel < 10) pw.print(' ');
13516            pw.print(r.trimMemoryLevel);
13517            pw.print(' ');
13518            pw.print(r.toShortString());
13519            pw.print(" (");
13520            pw.print(r.adjType);
13521            pw.println(')');
13522            if (r.adjSource != null || r.adjTarget != null) {
13523                pw.print(prefix);
13524                pw.print("    ");
13525                if (r.adjTarget instanceof ComponentName) {
13526                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13527                } else if (r.adjTarget != null) {
13528                    pw.print(r.adjTarget.toString());
13529                } else {
13530                    pw.print("{null}");
13531                }
13532                pw.print("<=");
13533                if (r.adjSource instanceof ProcessRecord) {
13534                    pw.print("Proc{");
13535                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13536                    pw.println("}");
13537                } else if (r.adjSource != null) {
13538                    pw.println(r.adjSource.toString());
13539                } else {
13540                    pw.println("{null}");
13541                }
13542            }
13543            if (inclDetails) {
13544                pw.print(prefix);
13545                pw.print("    ");
13546                pw.print("oom: max="); pw.print(r.maxAdj);
13547                pw.print(" curRaw="); pw.print(r.curRawAdj);
13548                pw.print(" setRaw="); pw.print(r.setRawAdj);
13549                pw.print(" cur="); pw.print(r.curAdj);
13550                pw.print(" set="); pw.println(r.setAdj);
13551                pw.print(prefix);
13552                pw.print("    ");
13553                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13554                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13555                pw.print(" lastPss="); pw.print(r.lastPss);
13556                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13557                pw.print(prefix);
13558                pw.print("    ");
13559                pw.print("cached="); pw.print(r.cached);
13560                pw.print(" empty="); pw.print(r.empty);
13561                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13562
13563                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13564                    if (r.lastWakeTime != 0) {
13565                        long wtime;
13566                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13567                        synchronized (stats) {
13568                            wtime = stats.getProcessWakeTime(r.info.uid,
13569                                    r.pid, curRealtime);
13570                        }
13571                        long timeUsed = wtime - r.lastWakeTime;
13572                        pw.print(prefix);
13573                        pw.print("    ");
13574                        pw.print("keep awake over ");
13575                        TimeUtils.formatDuration(realtimeSince, pw);
13576                        pw.print(" used ");
13577                        TimeUtils.formatDuration(timeUsed, pw);
13578                        pw.print(" (");
13579                        pw.print((timeUsed*100)/realtimeSince);
13580                        pw.println("%)");
13581                    }
13582                    if (r.lastCpuTime != 0) {
13583                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13584                        pw.print(prefix);
13585                        pw.print("    ");
13586                        pw.print("run cpu over ");
13587                        TimeUtils.formatDuration(uptimeSince, pw);
13588                        pw.print(" used ");
13589                        TimeUtils.formatDuration(timeUsed, pw);
13590                        pw.print(" (");
13591                        pw.print((timeUsed*100)/uptimeSince);
13592                        pw.println("%)");
13593                    }
13594                }
13595            }
13596        }
13597        return true;
13598    }
13599
13600    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13601        ArrayList<ProcessRecord> procs;
13602        synchronized (this) {
13603            if (args != null && args.length > start
13604                    && args[start].charAt(0) != '-') {
13605                procs = new ArrayList<ProcessRecord>();
13606                int pid = -1;
13607                try {
13608                    pid = Integer.parseInt(args[start]);
13609                } catch (NumberFormatException e) {
13610                }
13611                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13612                    ProcessRecord proc = mLruProcesses.get(i);
13613                    if (proc.pid == pid) {
13614                        procs.add(proc);
13615                    } else if (proc.processName.equals(args[start])) {
13616                        procs.add(proc);
13617                    }
13618                }
13619                if (procs.size() <= 0) {
13620                    return null;
13621                }
13622            } else {
13623                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13624            }
13625        }
13626        return procs;
13627    }
13628
13629    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13630            PrintWriter pw, String[] args) {
13631        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13632        if (procs == null) {
13633            pw.println("No process found for: " + args[0]);
13634            return;
13635        }
13636
13637        long uptime = SystemClock.uptimeMillis();
13638        long realtime = SystemClock.elapsedRealtime();
13639        pw.println("Applications Graphics Acceleration Info:");
13640        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13641
13642        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13643            ProcessRecord r = procs.get(i);
13644            if (r.thread != null) {
13645                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13646                pw.flush();
13647                try {
13648                    TransferPipe tp = new TransferPipe();
13649                    try {
13650                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13651                        tp.go(fd);
13652                    } finally {
13653                        tp.kill();
13654                    }
13655                } catch (IOException e) {
13656                    pw.println("Failure while dumping the app: " + r);
13657                    pw.flush();
13658                } catch (RemoteException e) {
13659                    pw.println("Got a RemoteException while dumping the app " + r);
13660                    pw.flush();
13661                }
13662            }
13663        }
13664    }
13665
13666    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13667        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13668        if (procs == null) {
13669            pw.println("No process found for: " + args[0]);
13670            return;
13671        }
13672
13673        pw.println("Applications Database Info:");
13674
13675        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13676            ProcessRecord r = procs.get(i);
13677            if (r.thread != null) {
13678                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13679                pw.flush();
13680                try {
13681                    TransferPipe tp = new TransferPipe();
13682                    try {
13683                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13684                        tp.go(fd);
13685                    } finally {
13686                        tp.kill();
13687                    }
13688                } catch (IOException e) {
13689                    pw.println("Failure while dumping the app: " + r);
13690                    pw.flush();
13691                } catch (RemoteException e) {
13692                    pw.println("Got a RemoteException while dumping the app " + r);
13693                    pw.flush();
13694                }
13695            }
13696        }
13697    }
13698
13699    final static class MemItem {
13700        final boolean isProc;
13701        final String label;
13702        final String shortLabel;
13703        final long pss;
13704        final int id;
13705        final boolean hasActivities;
13706        ArrayList<MemItem> subitems;
13707
13708        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13709                boolean _hasActivities) {
13710            isProc = true;
13711            label = _label;
13712            shortLabel = _shortLabel;
13713            pss = _pss;
13714            id = _id;
13715            hasActivities = _hasActivities;
13716        }
13717
13718        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13719            isProc = false;
13720            label = _label;
13721            shortLabel = _shortLabel;
13722            pss = _pss;
13723            id = _id;
13724            hasActivities = false;
13725        }
13726    }
13727
13728    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13729            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13730        if (sort && !isCompact) {
13731            Collections.sort(items, new Comparator<MemItem>() {
13732                @Override
13733                public int compare(MemItem lhs, MemItem rhs) {
13734                    if (lhs.pss < rhs.pss) {
13735                        return 1;
13736                    } else if (lhs.pss > rhs.pss) {
13737                        return -1;
13738                    }
13739                    return 0;
13740                }
13741            });
13742        }
13743
13744        for (int i=0; i<items.size(); i++) {
13745            MemItem mi = items.get(i);
13746            if (!isCompact) {
13747                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13748            } else if (mi.isProc) {
13749                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13750                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13751                pw.println(mi.hasActivities ? ",a" : ",e");
13752            } else {
13753                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13754                pw.println(mi.pss);
13755            }
13756            if (mi.subitems != null) {
13757                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13758                        true, isCompact);
13759            }
13760        }
13761    }
13762
13763    // These are in KB.
13764    static final long[] DUMP_MEM_BUCKETS = new long[] {
13765        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13766        120*1024, 160*1024, 200*1024,
13767        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13768        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13769    };
13770
13771    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13772            boolean stackLike) {
13773        int start = label.lastIndexOf('.');
13774        if (start >= 0) start++;
13775        else start = 0;
13776        int end = label.length();
13777        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13778            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13779                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13780                out.append(bucket);
13781                out.append(stackLike ? "MB." : "MB ");
13782                out.append(label, start, end);
13783                return;
13784            }
13785        }
13786        out.append(memKB/1024);
13787        out.append(stackLike ? "MB." : "MB ");
13788        out.append(label, start, end);
13789    }
13790
13791    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13792            ProcessList.NATIVE_ADJ,
13793            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13794            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13795            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13796            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13797            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13798    };
13799    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13800            "Native",
13801            "System", "Persistent", "Foreground",
13802            "Visible", "Perceptible",
13803            "Heavy Weight", "Backup",
13804            "A Services", "Home",
13805            "Previous", "B Services", "Cached"
13806    };
13807    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13808            "native",
13809            "sys", "pers", "fore",
13810            "vis", "percept",
13811            "heavy", "backup",
13812            "servicea", "home",
13813            "prev", "serviceb", "cached"
13814    };
13815
13816    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13817            long realtime, boolean isCheckinRequest, boolean isCompact) {
13818        if (isCheckinRequest || isCompact) {
13819            // short checkin version
13820            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13821        } else {
13822            pw.println("Applications Memory Usage (kB):");
13823            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13824        }
13825    }
13826
13827    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13828            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13829        boolean dumpDetails = false;
13830        boolean dumpFullDetails = false;
13831        boolean dumpDalvik = false;
13832        boolean oomOnly = false;
13833        boolean isCompact = false;
13834        boolean localOnly = false;
13835
13836        int opti = 0;
13837        while (opti < args.length) {
13838            String opt = args[opti];
13839            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13840                break;
13841            }
13842            opti++;
13843            if ("-a".equals(opt)) {
13844                dumpDetails = true;
13845                dumpFullDetails = true;
13846                dumpDalvik = true;
13847            } else if ("-d".equals(opt)) {
13848                dumpDalvik = true;
13849            } else if ("-c".equals(opt)) {
13850                isCompact = true;
13851            } else if ("--oom".equals(opt)) {
13852                oomOnly = true;
13853            } else if ("--local".equals(opt)) {
13854                localOnly = true;
13855            } else if ("-h".equals(opt)) {
13856                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13857                pw.println("  -a: include all available information for each process.");
13858                pw.println("  -d: include dalvik details when dumping process details.");
13859                pw.println("  -c: dump in a compact machine-parseable representation.");
13860                pw.println("  --oom: only show processes organized by oom adj.");
13861                pw.println("  --local: only collect details locally, don't call process.");
13862                pw.println("If [process] is specified it can be the name or ");
13863                pw.println("pid of a specific process to dump.");
13864                return;
13865            } else {
13866                pw.println("Unknown argument: " + opt + "; use -h for help");
13867            }
13868        }
13869
13870        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13871        long uptime = SystemClock.uptimeMillis();
13872        long realtime = SystemClock.elapsedRealtime();
13873        final long[] tmpLong = new long[1];
13874
13875        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13876        if (procs == null) {
13877            // No Java processes.  Maybe they want to print a native process.
13878            if (args != null && args.length > opti
13879                    && args[opti].charAt(0) != '-') {
13880                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13881                        = new ArrayList<ProcessCpuTracker.Stats>();
13882                updateCpuStatsNow();
13883                int findPid = -1;
13884                try {
13885                    findPid = Integer.parseInt(args[opti]);
13886                } catch (NumberFormatException e) {
13887                }
13888                synchronized (mProcessCpuTracker) {
13889                    final int N = mProcessCpuTracker.countStats();
13890                    for (int i=0; i<N; i++) {
13891                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13892                        if (st.pid == findPid || (st.baseName != null
13893                                && st.baseName.equals(args[opti]))) {
13894                            nativeProcs.add(st);
13895                        }
13896                    }
13897                }
13898                if (nativeProcs.size() > 0) {
13899                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13900                            isCompact);
13901                    Debug.MemoryInfo mi = null;
13902                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13903                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13904                        final int pid = r.pid;
13905                        if (!isCheckinRequest && dumpDetails) {
13906                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13907                        }
13908                        if (mi == null) {
13909                            mi = new Debug.MemoryInfo();
13910                        }
13911                        if (dumpDetails || (!brief && !oomOnly)) {
13912                            Debug.getMemoryInfo(pid, mi);
13913                        } else {
13914                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13915                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13916                        }
13917                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13918                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13919                        if (isCheckinRequest) {
13920                            pw.println();
13921                        }
13922                    }
13923                    return;
13924                }
13925            }
13926            pw.println("No process found for: " + args[opti]);
13927            return;
13928        }
13929
13930        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13931            dumpDetails = true;
13932        }
13933
13934        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13935
13936        String[] innerArgs = new String[args.length-opti];
13937        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13938
13939        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13940        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13941        long nativePss=0, dalvikPss=0, otherPss=0;
13942        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13943
13944        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13945        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13946                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13947
13948        long totalPss = 0;
13949        long cachedPss = 0;
13950
13951        Debug.MemoryInfo mi = null;
13952        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13953            final ProcessRecord r = procs.get(i);
13954            final IApplicationThread thread;
13955            final int pid;
13956            final int oomAdj;
13957            final boolean hasActivities;
13958            synchronized (this) {
13959                thread = r.thread;
13960                pid = r.pid;
13961                oomAdj = r.getSetAdjWithServices();
13962                hasActivities = r.activities.size() > 0;
13963            }
13964            if (thread != null) {
13965                if (!isCheckinRequest && dumpDetails) {
13966                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13967                }
13968                if (mi == null) {
13969                    mi = new Debug.MemoryInfo();
13970                }
13971                if (dumpDetails || (!brief && !oomOnly)) {
13972                    Debug.getMemoryInfo(pid, mi);
13973                } else {
13974                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13975                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13976                }
13977                if (dumpDetails) {
13978                    if (localOnly) {
13979                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13980                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13981                        if (isCheckinRequest) {
13982                            pw.println();
13983                        }
13984                    } else {
13985                        try {
13986                            pw.flush();
13987                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13988                                    dumpDalvik, innerArgs);
13989                        } catch (RemoteException e) {
13990                            if (!isCheckinRequest) {
13991                                pw.println("Got RemoteException!");
13992                                pw.flush();
13993                            }
13994                        }
13995                    }
13996                }
13997
13998                final long myTotalPss = mi.getTotalPss();
13999                final long myTotalUss = mi.getTotalUss();
14000
14001                synchronized (this) {
14002                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14003                        // Record this for posterity if the process has been stable.
14004                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14005                    }
14006                }
14007
14008                if (!isCheckinRequest && mi != null) {
14009                    totalPss += myTotalPss;
14010                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14011                            (hasActivities ? " / activities)" : ")"),
14012                            r.processName, myTotalPss, pid, hasActivities);
14013                    procMems.add(pssItem);
14014                    procMemsMap.put(pid, pssItem);
14015
14016                    nativePss += mi.nativePss;
14017                    dalvikPss += mi.dalvikPss;
14018                    otherPss += mi.otherPss;
14019                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14020                        long mem = mi.getOtherPss(j);
14021                        miscPss[j] += mem;
14022                        otherPss -= mem;
14023                    }
14024
14025                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14026                        cachedPss += myTotalPss;
14027                    }
14028
14029                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14030                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14031                                || oomIndex == (oomPss.length-1)) {
14032                            oomPss[oomIndex] += myTotalPss;
14033                            if (oomProcs[oomIndex] == null) {
14034                                oomProcs[oomIndex] = new ArrayList<MemItem>();
14035                            }
14036                            oomProcs[oomIndex].add(pssItem);
14037                            break;
14038                        }
14039                    }
14040                }
14041            }
14042        }
14043
14044        long nativeProcTotalPss = 0;
14045
14046        if (!isCheckinRequest && procs.size() > 1) {
14047            // If we are showing aggregations, also look for native processes to
14048            // include so that our aggregations are more accurate.
14049            updateCpuStatsNow();
14050            synchronized (mProcessCpuTracker) {
14051                final int N = mProcessCpuTracker.countStats();
14052                for (int i=0; i<N; i++) {
14053                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14054                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14055                        if (mi == null) {
14056                            mi = new Debug.MemoryInfo();
14057                        }
14058                        if (!brief && !oomOnly) {
14059                            Debug.getMemoryInfo(st.pid, mi);
14060                        } else {
14061                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14062                            mi.nativePrivateDirty = (int)tmpLong[0];
14063                        }
14064
14065                        final long myTotalPss = mi.getTotalPss();
14066                        totalPss += myTotalPss;
14067                        nativeProcTotalPss += myTotalPss;
14068
14069                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14070                                st.name, myTotalPss, st.pid, false);
14071                        procMems.add(pssItem);
14072
14073                        nativePss += mi.nativePss;
14074                        dalvikPss += mi.dalvikPss;
14075                        otherPss += mi.otherPss;
14076                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14077                            long mem = mi.getOtherPss(j);
14078                            miscPss[j] += mem;
14079                            otherPss -= mem;
14080                        }
14081                        oomPss[0] += myTotalPss;
14082                        if (oomProcs[0] == null) {
14083                            oomProcs[0] = new ArrayList<MemItem>();
14084                        }
14085                        oomProcs[0].add(pssItem);
14086                    }
14087                }
14088            }
14089
14090            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14091
14092            catMems.add(new MemItem("Native", "Native", nativePss, -1));
14093            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14094            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14095            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14096                String label = Debug.MemoryInfo.getOtherLabel(j);
14097                catMems.add(new MemItem(label, label, miscPss[j], j));
14098            }
14099
14100            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14101            for (int j=0; j<oomPss.length; j++) {
14102                if (oomPss[j] != 0) {
14103                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14104                            : DUMP_MEM_OOM_LABEL[j];
14105                    MemItem item = new MemItem(label, label, oomPss[j],
14106                            DUMP_MEM_OOM_ADJ[j]);
14107                    item.subitems = oomProcs[j];
14108                    oomMems.add(item);
14109                }
14110            }
14111
14112            if (!brief && !oomOnly && !isCompact) {
14113                pw.println();
14114                pw.println("Total PSS by process:");
14115                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
14116                pw.println();
14117            }
14118            if (!isCompact) {
14119                pw.println("Total PSS by OOM adjustment:");
14120            }
14121            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
14122            if (!brief && !oomOnly) {
14123                PrintWriter out = categoryPw != null ? categoryPw : pw;
14124                if (!isCompact) {
14125                    out.println();
14126                    out.println("Total PSS by category:");
14127                }
14128                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
14129            }
14130            if (!isCompact) {
14131                pw.println();
14132            }
14133            MemInfoReader memInfo = new MemInfoReader();
14134            memInfo.readMemInfo();
14135            if (nativeProcTotalPss > 0) {
14136                synchronized (this) {
14137                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14138                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14139                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14140                            nativeProcTotalPss);
14141                }
14142            }
14143            if (!brief) {
14144                if (!isCompact) {
14145                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14146                    pw.print(" kB (status ");
14147                    switch (mLastMemoryLevel) {
14148                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14149                            pw.println("normal)");
14150                            break;
14151                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14152                            pw.println("moderate)");
14153                            break;
14154                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
14155                            pw.println("low)");
14156                            break;
14157                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14158                            pw.println("critical)");
14159                            break;
14160                        default:
14161                            pw.print(mLastMemoryLevel);
14162                            pw.println(")");
14163                            break;
14164                    }
14165                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14166                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
14167                            pw.print(cachedPss); pw.print(" cached pss + ");
14168                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14169                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14170                } else {
14171                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14172                    pw.print(cachedPss + memInfo.getCachedSizeKb()
14173                            + memInfo.getFreeSizeKb()); pw.print(",");
14174                    pw.println(totalPss - cachedPss);
14175                }
14176            }
14177            if (!isCompact) {
14178                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14179                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14180                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
14181                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14182                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14183                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14184                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14185                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14186                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14187                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14188                        - memInfo.getSlabSizeKb()); pw.println(" kB");
14189            }
14190            if (!brief) {
14191                if (memInfo.getZramTotalSizeKb() != 0) {
14192                    if (!isCompact) {
14193                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14194                                pw.print(" kB physical used for ");
14195                                pw.print(memInfo.getSwapTotalSizeKb()
14196                                        - memInfo.getSwapFreeSizeKb());
14197                                pw.print(" kB in swap (");
14198                                pw.print(memInfo.getSwapTotalSizeKb());
14199                                pw.println(" kB total swap)");
14200                    } else {
14201                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14202                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14203                                pw.println(memInfo.getSwapFreeSizeKb());
14204                    }
14205                }
14206                final int[] SINGLE_LONG_FORMAT = new int[] {
14207                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14208                };
14209                long[] longOut = new long[1];
14210                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14211                        SINGLE_LONG_FORMAT, null, longOut, null);
14212                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14213                longOut[0] = 0;
14214                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14215                        SINGLE_LONG_FORMAT, null, longOut, null);
14216                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14217                longOut[0] = 0;
14218                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14219                        SINGLE_LONG_FORMAT, null, longOut, null);
14220                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14221                longOut[0] = 0;
14222                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14223                        SINGLE_LONG_FORMAT, null, longOut, null);
14224                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14225                if (!isCompact) {
14226                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14227                        pw.print("      KSM: "); pw.print(sharing);
14228                                pw.print(" kB saved from shared ");
14229                                pw.print(shared); pw.println(" kB");
14230                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14231                                pw.print(voltile); pw.println(" kB volatile");
14232                    }
14233                    pw.print("   Tuning: ");
14234                    pw.print(ActivityManager.staticGetMemoryClass());
14235                    pw.print(" (large ");
14236                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14237                    pw.print("), oom ");
14238                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14239                    pw.print(" kB");
14240                    pw.print(", restore limit ");
14241                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14242                    pw.print(" kB");
14243                    if (ActivityManager.isLowRamDeviceStatic()) {
14244                        pw.print(" (low-ram)");
14245                    }
14246                    if (ActivityManager.isHighEndGfx()) {
14247                        pw.print(" (high-end-gfx)");
14248                    }
14249                    pw.println();
14250                } else {
14251                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14252                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14253                    pw.println(voltile);
14254                    pw.print("tuning,");
14255                    pw.print(ActivityManager.staticGetMemoryClass());
14256                    pw.print(',');
14257                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14258                    pw.print(',');
14259                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14260                    if (ActivityManager.isLowRamDeviceStatic()) {
14261                        pw.print(",low-ram");
14262                    }
14263                    if (ActivityManager.isHighEndGfx()) {
14264                        pw.print(",high-end-gfx");
14265                    }
14266                    pw.println();
14267                }
14268            }
14269        }
14270    }
14271
14272    /**
14273     * Searches array of arguments for the specified string
14274     * @param args array of argument strings
14275     * @param value value to search for
14276     * @return true if the value is contained in the array
14277     */
14278    private static boolean scanArgs(String[] args, String value) {
14279        if (args != null) {
14280            for (String arg : args) {
14281                if (value.equals(arg)) {
14282                    return true;
14283                }
14284            }
14285        }
14286        return false;
14287    }
14288
14289    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14290            ContentProviderRecord cpr, boolean always) {
14291        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14292
14293        if (!inLaunching || always) {
14294            synchronized (cpr) {
14295                cpr.launchingApp = null;
14296                cpr.notifyAll();
14297            }
14298            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14299            String names[] = cpr.info.authority.split(";");
14300            for (int j = 0; j < names.length; j++) {
14301                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14302            }
14303        }
14304
14305        for (int i=0; i<cpr.connections.size(); i++) {
14306            ContentProviderConnection conn = cpr.connections.get(i);
14307            if (conn.waiting) {
14308                // If this connection is waiting for the provider, then we don't
14309                // need to mess with its process unless we are always removing
14310                // or for some reason the provider is not currently launching.
14311                if (inLaunching && !always) {
14312                    continue;
14313                }
14314            }
14315            ProcessRecord capp = conn.client;
14316            conn.dead = true;
14317            if (conn.stableCount > 0) {
14318                if (!capp.persistent && capp.thread != null
14319                        && capp.pid != 0
14320                        && capp.pid != MY_PID) {
14321                    capp.kill("depends on provider "
14322                            + cpr.name.flattenToShortString()
14323                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14324                }
14325            } else if (capp.thread != null && conn.provider.provider != null) {
14326                try {
14327                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14328                } catch (RemoteException e) {
14329                }
14330                // In the protocol here, we don't expect the client to correctly
14331                // clean up this connection, we'll just remove it.
14332                cpr.connections.remove(i);
14333                conn.client.conProviders.remove(conn);
14334            }
14335        }
14336
14337        if (inLaunching && always) {
14338            mLaunchingProviders.remove(cpr);
14339        }
14340        return inLaunching;
14341    }
14342
14343    /**
14344     * Main code for cleaning up a process when it has gone away.  This is
14345     * called both as a result of the process dying, or directly when stopping
14346     * a process when running in single process mode.
14347     *
14348     * @return Returns true if the given process has been restarted, so the
14349     * app that was passed in must remain on the process lists.
14350     */
14351    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14352            boolean restarting, boolean allowRestart, int index) {
14353        if (index >= 0) {
14354            removeLruProcessLocked(app);
14355            ProcessList.remove(app.pid);
14356        }
14357
14358        mProcessesToGc.remove(app);
14359        mPendingPssProcesses.remove(app);
14360
14361        // Dismiss any open dialogs.
14362        if (app.crashDialog != null && !app.forceCrashReport) {
14363            app.crashDialog.dismiss();
14364            app.crashDialog = null;
14365        }
14366        if (app.anrDialog != null) {
14367            app.anrDialog.dismiss();
14368            app.anrDialog = null;
14369        }
14370        if (app.waitDialog != null) {
14371            app.waitDialog.dismiss();
14372            app.waitDialog = null;
14373        }
14374
14375        app.crashing = false;
14376        app.notResponding = false;
14377
14378        app.resetPackageList(mProcessStats);
14379        app.unlinkDeathRecipient();
14380        app.makeInactive(mProcessStats);
14381        app.waitingToKill = null;
14382        app.forcingToForeground = null;
14383        updateProcessForegroundLocked(app, false, false);
14384        app.foregroundActivities = false;
14385        app.hasShownUi = false;
14386        app.treatLikeActivity = false;
14387        app.hasAboveClient = false;
14388        app.hasClientActivities = false;
14389
14390        mServices.killServicesLocked(app, allowRestart);
14391
14392        boolean restart = false;
14393
14394        // Remove published content providers.
14395        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14396            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14397            final boolean always = app.bad || !allowRestart;
14398            if (removeDyingProviderLocked(app, cpr, always) || always) {
14399                // We left the provider in the launching list, need to
14400                // restart it.
14401                restart = true;
14402            }
14403
14404            cpr.provider = null;
14405            cpr.proc = null;
14406        }
14407        app.pubProviders.clear();
14408
14409        // Take care of any launching providers waiting for this process.
14410        if (checkAppInLaunchingProvidersLocked(app, false)) {
14411            restart = true;
14412        }
14413
14414        // Unregister from connected content providers.
14415        if (!app.conProviders.isEmpty()) {
14416            for (int i=0; i<app.conProviders.size(); i++) {
14417                ContentProviderConnection conn = app.conProviders.get(i);
14418                conn.provider.connections.remove(conn);
14419            }
14420            app.conProviders.clear();
14421        }
14422
14423        // At this point there may be remaining entries in mLaunchingProviders
14424        // where we were the only one waiting, so they are no longer of use.
14425        // Look for these and clean up if found.
14426        // XXX Commented out for now.  Trying to figure out a way to reproduce
14427        // the actual situation to identify what is actually going on.
14428        if (false) {
14429            for (int i=0; i<mLaunchingProviders.size(); i++) {
14430                ContentProviderRecord cpr = (ContentProviderRecord)
14431                        mLaunchingProviders.get(i);
14432                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14433                    synchronized (cpr) {
14434                        cpr.launchingApp = null;
14435                        cpr.notifyAll();
14436                    }
14437                }
14438            }
14439        }
14440
14441        skipCurrentReceiverLocked(app);
14442
14443        // Unregister any receivers.
14444        for (int i=app.receivers.size()-1; i>=0; i--) {
14445            removeReceiverLocked(app.receivers.valueAt(i));
14446        }
14447        app.receivers.clear();
14448
14449        // If the app is undergoing backup, tell the backup manager about it
14450        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14451            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14452                    + mBackupTarget.appInfo + " died during backup");
14453            try {
14454                IBackupManager bm = IBackupManager.Stub.asInterface(
14455                        ServiceManager.getService(Context.BACKUP_SERVICE));
14456                bm.agentDisconnected(app.info.packageName);
14457            } catch (RemoteException e) {
14458                // can't happen; backup manager is local
14459            }
14460        }
14461
14462        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14463            ProcessChangeItem item = mPendingProcessChanges.get(i);
14464            if (item.pid == app.pid) {
14465                mPendingProcessChanges.remove(i);
14466                mAvailProcessChanges.add(item);
14467            }
14468        }
14469        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14470
14471        // If the caller is restarting this app, then leave it in its
14472        // current lists and let the caller take care of it.
14473        if (restarting) {
14474            return false;
14475        }
14476
14477        if (!app.persistent || app.isolated) {
14478            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14479                    "Removing non-persistent process during cleanup: " + app);
14480            mProcessNames.remove(app.processName, app.uid);
14481            mIsolatedProcesses.remove(app.uid);
14482            if (mHeavyWeightProcess == app) {
14483                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14484                        mHeavyWeightProcess.userId, 0));
14485                mHeavyWeightProcess = null;
14486            }
14487        } else if (!app.removed) {
14488            // This app is persistent, so we need to keep its record around.
14489            // If it is not already on the pending app list, add it there
14490            // and start a new process for it.
14491            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14492                mPersistentStartingProcesses.add(app);
14493                restart = true;
14494            }
14495        }
14496        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14497                "Clean-up removing on hold: " + app);
14498        mProcessesOnHold.remove(app);
14499
14500        if (app == mHomeProcess) {
14501            mHomeProcess = null;
14502        }
14503        if (app == mPreviousProcess) {
14504            mPreviousProcess = null;
14505        }
14506
14507        if (restart && !app.isolated) {
14508            // We have components that still need to be running in the
14509            // process, so re-launch it.
14510            if (index < 0) {
14511                ProcessList.remove(app.pid);
14512            }
14513            mProcessNames.put(app.processName, app.uid, app);
14514            startProcessLocked(app, "restart", app.processName);
14515            return true;
14516        } else if (app.pid > 0 && app.pid != MY_PID) {
14517            // Goodbye!
14518            boolean removed;
14519            synchronized (mPidsSelfLocked) {
14520                mPidsSelfLocked.remove(app.pid);
14521                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14522            }
14523            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14524            if (app.isolated) {
14525                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14526            }
14527            app.setPid(0);
14528        }
14529        return false;
14530    }
14531
14532    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14533        // Look through the content providers we are waiting to have launched,
14534        // and if any run in this process then either schedule a restart of
14535        // the process or kill the client waiting for it if this process has
14536        // gone bad.
14537        int NL = mLaunchingProviders.size();
14538        boolean restart = false;
14539        for (int i=0; i<NL; i++) {
14540            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14541            if (cpr.launchingApp == app) {
14542                if (!alwaysBad && !app.bad) {
14543                    restart = true;
14544                } else {
14545                    removeDyingProviderLocked(app, cpr, true);
14546                    // cpr should have been removed from mLaunchingProviders
14547                    NL = mLaunchingProviders.size();
14548                    i--;
14549                }
14550            }
14551        }
14552        return restart;
14553    }
14554
14555    // =========================================================
14556    // SERVICES
14557    // =========================================================
14558
14559    @Override
14560    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14561            int flags) {
14562        enforceNotIsolatedCaller("getServices");
14563        synchronized (this) {
14564            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14565        }
14566    }
14567
14568    @Override
14569    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14570        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14571        synchronized (this) {
14572            return mServices.getRunningServiceControlPanelLocked(name);
14573        }
14574    }
14575
14576    @Override
14577    public ComponentName startService(IApplicationThread caller, Intent service,
14578            String resolvedType, int userId) {
14579        enforceNotIsolatedCaller("startService");
14580        // Refuse possible leaked file descriptors
14581        if (service != null && service.hasFileDescriptors() == true) {
14582            throw new IllegalArgumentException("File descriptors passed in Intent");
14583        }
14584
14585        if (DEBUG_SERVICE)
14586            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14587        synchronized(this) {
14588            final int callingPid = Binder.getCallingPid();
14589            final int callingUid = Binder.getCallingUid();
14590            final long origId = Binder.clearCallingIdentity();
14591            ComponentName res = mServices.startServiceLocked(caller, service,
14592                    resolvedType, callingPid, callingUid, userId);
14593            Binder.restoreCallingIdentity(origId);
14594            return res;
14595        }
14596    }
14597
14598    ComponentName startServiceInPackage(int uid,
14599            Intent service, String resolvedType, int userId) {
14600        synchronized(this) {
14601            if (DEBUG_SERVICE)
14602                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14603            final long origId = Binder.clearCallingIdentity();
14604            ComponentName res = mServices.startServiceLocked(null, service,
14605                    resolvedType, -1, uid, userId);
14606            Binder.restoreCallingIdentity(origId);
14607            return res;
14608        }
14609    }
14610
14611    @Override
14612    public int stopService(IApplicationThread caller, Intent service,
14613            String resolvedType, int userId) {
14614        enforceNotIsolatedCaller("stopService");
14615        // Refuse possible leaked file descriptors
14616        if (service != null && service.hasFileDescriptors() == true) {
14617            throw new IllegalArgumentException("File descriptors passed in Intent");
14618        }
14619
14620        synchronized(this) {
14621            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14622        }
14623    }
14624
14625    @Override
14626    public IBinder peekService(Intent service, String resolvedType) {
14627        enforceNotIsolatedCaller("peekService");
14628        // Refuse possible leaked file descriptors
14629        if (service != null && service.hasFileDescriptors() == true) {
14630            throw new IllegalArgumentException("File descriptors passed in Intent");
14631        }
14632        synchronized(this) {
14633            return mServices.peekServiceLocked(service, resolvedType);
14634        }
14635    }
14636
14637    @Override
14638    public boolean stopServiceToken(ComponentName className, IBinder token,
14639            int startId) {
14640        synchronized(this) {
14641            return mServices.stopServiceTokenLocked(className, token, startId);
14642        }
14643    }
14644
14645    @Override
14646    public void setServiceForeground(ComponentName className, IBinder token,
14647            int id, Notification notification, boolean removeNotification) {
14648        synchronized(this) {
14649            mServices.setServiceForegroundLocked(className, token, id, notification,
14650                    removeNotification);
14651        }
14652    }
14653
14654    @Override
14655    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14656            boolean requireFull, String name, String callerPackage) {
14657        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14658                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14659    }
14660
14661    int unsafeConvertIncomingUser(int userId) {
14662        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14663                ? mCurrentUserId : userId;
14664    }
14665
14666    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14667            int allowMode, String name, String callerPackage) {
14668        final int callingUserId = UserHandle.getUserId(callingUid);
14669        if (callingUserId == userId) {
14670            return userId;
14671        }
14672
14673        // Note that we may be accessing mCurrentUserId outside of a lock...
14674        // shouldn't be a big deal, if this is being called outside
14675        // of a locked context there is intrinsically a race with
14676        // the value the caller will receive and someone else changing it.
14677        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14678        // we will switch to the calling user if access to the current user fails.
14679        int targetUserId = unsafeConvertIncomingUser(userId);
14680
14681        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14682            final boolean allow;
14683            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14684                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14685                // If the caller has this permission, they always pass go.  And collect $200.
14686                allow = true;
14687            } else if (allowMode == ALLOW_FULL_ONLY) {
14688                // We require full access, sucks to be you.
14689                allow = false;
14690            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14691                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14692                // If the caller does not have either permission, they are always doomed.
14693                allow = false;
14694            } else if (allowMode == ALLOW_NON_FULL) {
14695                // We are blanket allowing non-full access, you lucky caller!
14696                allow = true;
14697            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14698                // We may or may not allow this depending on whether the two users are
14699                // in the same profile.
14700                synchronized (mUserProfileGroupIdsSelfLocked) {
14701                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14702                            UserInfo.NO_PROFILE_GROUP_ID);
14703                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14704                            UserInfo.NO_PROFILE_GROUP_ID);
14705                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14706                            && callingProfile == targetProfile;
14707                }
14708            } else {
14709                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14710            }
14711            if (!allow) {
14712                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14713                    // In this case, they would like to just execute as their
14714                    // owner user instead of failing.
14715                    targetUserId = callingUserId;
14716                } else {
14717                    StringBuilder builder = new StringBuilder(128);
14718                    builder.append("Permission Denial: ");
14719                    builder.append(name);
14720                    if (callerPackage != null) {
14721                        builder.append(" from ");
14722                        builder.append(callerPackage);
14723                    }
14724                    builder.append(" asks to run as user ");
14725                    builder.append(userId);
14726                    builder.append(" but is calling from user ");
14727                    builder.append(UserHandle.getUserId(callingUid));
14728                    builder.append("; this requires ");
14729                    builder.append(INTERACT_ACROSS_USERS_FULL);
14730                    if (allowMode != ALLOW_FULL_ONLY) {
14731                        builder.append(" or ");
14732                        builder.append(INTERACT_ACROSS_USERS);
14733                    }
14734                    String msg = builder.toString();
14735                    Slog.w(TAG, msg);
14736                    throw new SecurityException(msg);
14737                }
14738            }
14739        }
14740        if (!allowAll && targetUserId < 0) {
14741            throw new IllegalArgumentException(
14742                    "Call does not support special user #" + targetUserId);
14743        }
14744        // Check shell permission
14745        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14746            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14747                    targetUserId)) {
14748                throw new SecurityException("Shell does not have permission to access user "
14749                        + targetUserId + "\n " + Debug.getCallers(3));
14750            }
14751        }
14752        return targetUserId;
14753    }
14754
14755    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14756            String className, int flags) {
14757        boolean result = false;
14758        // For apps that don't have pre-defined UIDs, check for permission
14759        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14760            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14761                if (ActivityManager.checkUidPermission(
14762                        INTERACT_ACROSS_USERS,
14763                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14764                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14765                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14766                            + " requests FLAG_SINGLE_USER, but app does not hold "
14767                            + INTERACT_ACROSS_USERS;
14768                    Slog.w(TAG, msg);
14769                    throw new SecurityException(msg);
14770                }
14771                // Permission passed
14772                result = true;
14773            }
14774        } else if ("system".equals(componentProcessName)) {
14775            result = true;
14776        } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14777            // Phone app and persistent apps are allowed to export singleuser providers.
14778            result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14779                    || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14780        }
14781        if (DEBUG_MU) {
14782            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14783                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14784        }
14785        return result;
14786    }
14787
14788    /**
14789     * Checks to see if the caller is in the same app as the singleton
14790     * component, or the component is in a special app. It allows special apps
14791     * to export singleton components but prevents exporting singleton
14792     * components for regular apps.
14793     */
14794    boolean isValidSingletonCall(int callingUid, int componentUid) {
14795        int componentAppId = UserHandle.getAppId(componentUid);
14796        return UserHandle.isSameApp(callingUid, componentUid)
14797                || componentAppId == Process.SYSTEM_UID
14798                || componentAppId == Process.PHONE_UID
14799                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14800                        == PackageManager.PERMISSION_GRANTED;
14801    }
14802
14803    public int bindService(IApplicationThread caller, IBinder token,
14804            Intent service, String resolvedType,
14805            IServiceConnection connection, int flags, int userId) {
14806        enforceNotIsolatedCaller("bindService");
14807
14808        // Refuse possible leaked file descriptors
14809        if (service != null && service.hasFileDescriptors() == true) {
14810            throw new IllegalArgumentException("File descriptors passed in Intent");
14811        }
14812
14813        synchronized(this) {
14814            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14815                    connection, flags, userId);
14816        }
14817    }
14818
14819    public boolean unbindService(IServiceConnection connection) {
14820        synchronized (this) {
14821            return mServices.unbindServiceLocked(connection);
14822        }
14823    }
14824
14825    public void publishService(IBinder token, Intent intent, IBinder service) {
14826        // Refuse possible leaked file descriptors
14827        if (intent != null && intent.hasFileDescriptors() == true) {
14828            throw new IllegalArgumentException("File descriptors passed in Intent");
14829        }
14830
14831        synchronized(this) {
14832            if (!(token instanceof ServiceRecord)) {
14833                throw new IllegalArgumentException("Invalid service token");
14834            }
14835            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14836        }
14837    }
14838
14839    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14840        // Refuse possible leaked file descriptors
14841        if (intent != null && intent.hasFileDescriptors() == true) {
14842            throw new IllegalArgumentException("File descriptors passed in Intent");
14843        }
14844
14845        synchronized(this) {
14846            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14847        }
14848    }
14849
14850    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14851        synchronized(this) {
14852            if (!(token instanceof ServiceRecord)) {
14853                throw new IllegalArgumentException("Invalid service token");
14854            }
14855            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14856        }
14857    }
14858
14859    // =========================================================
14860    // BACKUP AND RESTORE
14861    // =========================================================
14862
14863    // Cause the target app to be launched if necessary and its backup agent
14864    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14865    // activity manager to announce its creation.
14866    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14867        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14868        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14869
14870        synchronized(this) {
14871            // !!! TODO: currently no check here that we're already bound
14872            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14873            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14874            synchronized (stats) {
14875                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14876            }
14877
14878            // Backup agent is now in use, its package can't be stopped.
14879            try {
14880                AppGlobals.getPackageManager().setPackageStoppedState(
14881                        app.packageName, false, UserHandle.getUserId(app.uid));
14882            } catch (RemoteException e) {
14883            } catch (IllegalArgumentException e) {
14884                Slog.w(TAG, "Failed trying to unstop package "
14885                        + app.packageName + ": " + e);
14886            }
14887
14888            BackupRecord r = new BackupRecord(ss, app, backupMode);
14889            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14890                    ? new ComponentName(app.packageName, app.backupAgentName)
14891                    : new ComponentName("android", "FullBackupAgent");
14892            // startProcessLocked() returns existing proc's record if it's already running
14893            ProcessRecord proc = startProcessLocked(app.processName, app,
14894                    false, 0, "backup", hostingName, false, false, false);
14895            if (proc == null) {
14896                Slog.e(TAG, "Unable to start backup agent process " + r);
14897                return false;
14898            }
14899
14900            r.app = proc;
14901            mBackupTarget = r;
14902            mBackupAppName = app.packageName;
14903
14904            // Try not to kill the process during backup
14905            updateOomAdjLocked(proc);
14906
14907            // If the process is already attached, schedule the creation of the backup agent now.
14908            // If it is not yet live, this will be done when it attaches to the framework.
14909            if (proc.thread != null) {
14910                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14911                try {
14912                    proc.thread.scheduleCreateBackupAgent(app,
14913                            compatibilityInfoForPackageLocked(app), backupMode);
14914                } catch (RemoteException e) {
14915                    // Will time out on the backup manager side
14916                }
14917            } else {
14918                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14919            }
14920            // Invariants: at this point, the target app process exists and the application
14921            // is either already running or in the process of coming up.  mBackupTarget and
14922            // mBackupAppName describe the app, so that when it binds back to the AM we
14923            // know that it's scheduled for a backup-agent operation.
14924        }
14925
14926        return true;
14927    }
14928
14929    @Override
14930    public void clearPendingBackup() {
14931        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14932        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14933
14934        synchronized (this) {
14935            mBackupTarget = null;
14936            mBackupAppName = null;
14937        }
14938    }
14939
14940    // A backup agent has just come up
14941    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14942        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14943                + " = " + agent);
14944
14945        synchronized(this) {
14946            if (!agentPackageName.equals(mBackupAppName)) {
14947                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14948                return;
14949            }
14950        }
14951
14952        long oldIdent = Binder.clearCallingIdentity();
14953        try {
14954            IBackupManager bm = IBackupManager.Stub.asInterface(
14955                    ServiceManager.getService(Context.BACKUP_SERVICE));
14956            bm.agentConnected(agentPackageName, agent);
14957        } catch (RemoteException e) {
14958            // can't happen; the backup manager service is local
14959        } catch (Exception e) {
14960            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14961            e.printStackTrace();
14962        } finally {
14963            Binder.restoreCallingIdentity(oldIdent);
14964        }
14965    }
14966
14967    // done with this agent
14968    public void unbindBackupAgent(ApplicationInfo appInfo) {
14969        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14970        if (appInfo == null) {
14971            Slog.w(TAG, "unbind backup agent for null app");
14972            return;
14973        }
14974
14975        synchronized(this) {
14976            try {
14977                if (mBackupAppName == null) {
14978                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14979                    return;
14980                }
14981
14982                if (!mBackupAppName.equals(appInfo.packageName)) {
14983                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14984                    return;
14985                }
14986
14987                // Not backing this app up any more; reset its OOM adjustment
14988                final ProcessRecord proc = mBackupTarget.app;
14989                updateOomAdjLocked(proc);
14990
14991                // If the app crashed during backup, 'thread' will be null here
14992                if (proc.thread != null) {
14993                    try {
14994                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14995                                compatibilityInfoForPackageLocked(appInfo));
14996                    } catch (Exception e) {
14997                        Slog.e(TAG, "Exception when unbinding backup agent:");
14998                        e.printStackTrace();
14999                    }
15000                }
15001            } finally {
15002                mBackupTarget = null;
15003                mBackupAppName = null;
15004            }
15005        }
15006    }
15007    // =========================================================
15008    // BROADCASTS
15009    // =========================================================
15010
15011    private final List getStickiesLocked(String action, IntentFilter filter,
15012            List cur, int userId) {
15013        final ContentResolver resolver = mContext.getContentResolver();
15014        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15015        if (stickies == null) {
15016            return cur;
15017        }
15018        final ArrayList<Intent> list = stickies.get(action);
15019        if (list == null) {
15020            return cur;
15021        }
15022        int N = list.size();
15023        for (int i=0; i<N; i++) {
15024            Intent intent = list.get(i);
15025            if (filter.match(resolver, intent, true, TAG) >= 0) {
15026                if (cur == null) {
15027                    cur = new ArrayList<Intent>();
15028                }
15029                cur.add(intent);
15030            }
15031        }
15032        return cur;
15033    }
15034
15035    boolean isPendingBroadcastProcessLocked(int pid) {
15036        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15037                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15038    }
15039
15040    void skipPendingBroadcastLocked(int pid) {
15041            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15042            for (BroadcastQueue queue : mBroadcastQueues) {
15043                queue.skipPendingBroadcastLocked(pid);
15044            }
15045    }
15046
15047    // The app just attached; send any pending broadcasts that it should receive
15048    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15049        boolean didSomething = false;
15050        for (BroadcastQueue queue : mBroadcastQueues) {
15051            didSomething |= queue.sendPendingBroadcastsLocked(app);
15052        }
15053        return didSomething;
15054    }
15055
15056    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15057            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15058        enforceNotIsolatedCaller("registerReceiver");
15059        int callingUid;
15060        int callingPid;
15061        synchronized(this) {
15062            ProcessRecord callerApp = null;
15063            if (caller != null) {
15064                callerApp = getRecordForAppLocked(caller);
15065                if (callerApp == null) {
15066                    throw new SecurityException(
15067                            "Unable to find app for caller " + caller
15068                            + " (pid=" + Binder.getCallingPid()
15069                            + ") when registering receiver " + receiver);
15070                }
15071                if (callerApp.info.uid != Process.SYSTEM_UID &&
15072                        !callerApp.pkgList.containsKey(callerPackage) &&
15073                        !"android".equals(callerPackage)) {
15074                    throw new SecurityException("Given caller package " + callerPackage
15075                            + " is not running in process " + callerApp);
15076                }
15077                callingUid = callerApp.info.uid;
15078                callingPid = callerApp.pid;
15079            } else {
15080                callerPackage = null;
15081                callingUid = Binder.getCallingUid();
15082                callingPid = Binder.getCallingPid();
15083            }
15084
15085            userId = this.handleIncomingUser(callingPid, callingUid, userId,
15086                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15087
15088            List allSticky = null;
15089
15090            // Look for any matching sticky broadcasts...
15091            Iterator actions = filter.actionsIterator();
15092            if (actions != null) {
15093                while (actions.hasNext()) {
15094                    String action = (String)actions.next();
15095                    allSticky = getStickiesLocked(action, filter, allSticky,
15096                            UserHandle.USER_ALL);
15097                    allSticky = getStickiesLocked(action, filter, allSticky,
15098                            UserHandle.getUserId(callingUid));
15099                }
15100            } else {
15101                allSticky = getStickiesLocked(null, filter, allSticky,
15102                        UserHandle.USER_ALL);
15103                allSticky = getStickiesLocked(null, filter, allSticky,
15104                        UserHandle.getUserId(callingUid));
15105            }
15106
15107            // The first sticky in the list is returned directly back to
15108            // the client.
15109            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15110
15111            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15112                    + ": " + sticky);
15113
15114            if (receiver == null) {
15115                return sticky;
15116            }
15117
15118            ReceiverList rl
15119                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15120            if (rl == null) {
15121                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15122                        userId, receiver);
15123                if (rl.app != null) {
15124                    rl.app.receivers.add(rl);
15125                } else {
15126                    try {
15127                        receiver.asBinder().linkToDeath(rl, 0);
15128                    } catch (RemoteException e) {
15129                        return sticky;
15130                    }
15131                    rl.linkedToDeath = true;
15132                }
15133                mRegisteredReceivers.put(receiver.asBinder(), rl);
15134            } else if (rl.uid != callingUid) {
15135                throw new IllegalArgumentException(
15136                        "Receiver requested to register for uid " + callingUid
15137                        + " was previously registered for uid " + rl.uid);
15138            } else if (rl.pid != callingPid) {
15139                throw new IllegalArgumentException(
15140                        "Receiver requested to register for pid " + callingPid
15141                        + " was previously registered for pid " + rl.pid);
15142            } else if (rl.userId != userId) {
15143                throw new IllegalArgumentException(
15144                        "Receiver requested to register for user " + userId
15145                        + " was previously registered for user " + rl.userId);
15146            }
15147            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15148                    permission, callingUid, userId);
15149            rl.add(bf);
15150            if (!bf.debugCheck()) {
15151                Slog.w(TAG, "==> For Dynamic broadast");
15152            }
15153            mReceiverResolver.addFilter(bf);
15154
15155            // Enqueue broadcasts for all existing stickies that match
15156            // this filter.
15157            if (allSticky != null) {
15158                ArrayList receivers = new ArrayList();
15159                receivers.add(bf);
15160
15161                int N = allSticky.size();
15162                for (int i=0; i<N; i++) {
15163                    Intent intent = (Intent)allSticky.get(i);
15164                    BroadcastQueue queue = broadcastQueueForIntent(intent);
15165                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15166                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15167                            null, null, false, true, true, -1);
15168                    queue.enqueueParallelBroadcastLocked(r);
15169                    queue.scheduleBroadcastsLocked();
15170                }
15171            }
15172
15173            return sticky;
15174        }
15175    }
15176
15177    public void unregisterReceiver(IIntentReceiver receiver) {
15178        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15179
15180        final long origId = Binder.clearCallingIdentity();
15181        try {
15182            boolean doTrim = false;
15183
15184            synchronized(this) {
15185                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15186                if (rl != null) {
15187                    if (rl.curBroadcast != null) {
15188                        BroadcastRecord r = rl.curBroadcast;
15189                        final boolean doNext = finishReceiverLocked(
15190                                receiver.asBinder(), r.resultCode, r.resultData,
15191                                r.resultExtras, r.resultAbort);
15192                        if (doNext) {
15193                            doTrim = true;
15194                            r.queue.processNextBroadcast(false);
15195                        }
15196                    }
15197
15198                    if (rl.app != null) {
15199                        rl.app.receivers.remove(rl);
15200                    }
15201                    removeReceiverLocked(rl);
15202                    if (rl.linkedToDeath) {
15203                        rl.linkedToDeath = false;
15204                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
15205                    }
15206                }
15207            }
15208
15209            // If we actually concluded any broadcasts, we might now be able
15210            // to trim the recipients' apps from our working set
15211            if (doTrim) {
15212                trimApplications();
15213                return;
15214            }
15215
15216        } finally {
15217            Binder.restoreCallingIdentity(origId);
15218        }
15219    }
15220
15221    void removeReceiverLocked(ReceiverList rl) {
15222        mRegisteredReceivers.remove(rl.receiver.asBinder());
15223        int N = rl.size();
15224        for (int i=0; i<N; i++) {
15225            mReceiverResolver.removeFilter(rl.get(i));
15226        }
15227    }
15228
15229    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15230        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15231            ProcessRecord r = mLruProcesses.get(i);
15232            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15233                try {
15234                    r.thread.dispatchPackageBroadcast(cmd, packages);
15235                } catch (RemoteException ex) {
15236                }
15237            }
15238        }
15239    }
15240
15241    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15242            int callingUid, int[] users) {
15243        List<ResolveInfo> receivers = null;
15244        try {
15245            HashSet<ComponentName> singleUserReceivers = null;
15246            boolean scannedFirstReceivers = false;
15247            for (int user : users) {
15248                // Skip users that have Shell restrictions
15249                if (callingUid == Process.SHELL_UID
15250                        && getUserManagerLocked().hasUserRestriction(
15251                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15252                    continue;
15253                }
15254                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15255                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15256                if (user != 0 && newReceivers != null) {
15257                    // If this is not the primary user, we need to check for
15258                    // any receivers that should be filtered out.
15259                    for (int i=0; i<newReceivers.size(); i++) {
15260                        ResolveInfo ri = newReceivers.get(i);
15261                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15262                            newReceivers.remove(i);
15263                            i--;
15264                        }
15265                    }
15266                }
15267                if (newReceivers != null && newReceivers.size() == 0) {
15268                    newReceivers = null;
15269                }
15270                if (receivers == null) {
15271                    receivers = newReceivers;
15272                } else if (newReceivers != null) {
15273                    // We need to concatenate the additional receivers
15274                    // found with what we have do far.  This would be easy,
15275                    // but we also need to de-dup any receivers that are
15276                    // singleUser.
15277                    if (!scannedFirstReceivers) {
15278                        // Collect any single user receivers we had already retrieved.
15279                        scannedFirstReceivers = true;
15280                        for (int i=0; i<receivers.size(); i++) {
15281                            ResolveInfo ri = receivers.get(i);
15282                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15283                                ComponentName cn = new ComponentName(
15284                                        ri.activityInfo.packageName, ri.activityInfo.name);
15285                                if (singleUserReceivers == null) {
15286                                    singleUserReceivers = new HashSet<ComponentName>();
15287                                }
15288                                singleUserReceivers.add(cn);
15289                            }
15290                        }
15291                    }
15292                    // Add the new results to the existing results, tracking
15293                    // and de-dupping single user receivers.
15294                    for (int i=0; i<newReceivers.size(); i++) {
15295                        ResolveInfo ri = newReceivers.get(i);
15296                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15297                            ComponentName cn = new ComponentName(
15298                                    ri.activityInfo.packageName, ri.activityInfo.name);
15299                            if (singleUserReceivers == null) {
15300                                singleUserReceivers = new HashSet<ComponentName>();
15301                            }
15302                            if (!singleUserReceivers.contains(cn)) {
15303                                singleUserReceivers.add(cn);
15304                                receivers.add(ri);
15305                            }
15306                        } else {
15307                            receivers.add(ri);
15308                        }
15309                    }
15310                }
15311            }
15312        } catch (RemoteException ex) {
15313            // pm is in same process, this will never happen.
15314        }
15315        return receivers;
15316    }
15317
15318    private final int broadcastIntentLocked(ProcessRecord callerApp,
15319            String callerPackage, Intent intent, String resolvedType,
15320            IIntentReceiver resultTo, int resultCode, String resultData,
15321            Bundle map, String requiredPermission, int appOp,
15322            boolean ordered, boolean sticky, int callingPid, int callingUid,
15323            int userId) {
15324        intent = new Intent(intent);
15325
15326        // By default broadcasts do not go to stopped apps.
15327        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15328
15329        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15330            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15331            + " ordered=" + ordered + " userid=" + userId);
15332        if ((resultTo != null) && !ordered) {
15333            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15334        }
15335
15336        userId = handleIncomingUser(callingPid, callingUid, userId,
15337                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15338
15339        // Make sure that the user who is receiving this broadcast is started.
15340        // If not, we will just skip it.
15341
15342        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15343            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15344                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15345                Slog.w(TAG, "Skipping broadcast of " + intent
15346                        + ": user " + userId + " is stopped");
15347                return ActivityManager.BROADCAST_SUCCESS;
15348            }
15349        }
15350
15351        /*
15352         * Prevent non-system code (defined here to be non-persistent
15353         * processes) from sending protected broadcasts.
15354         */
15355        int callingAppId = UserHandle.getAppId(callingUid);
15356        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15357            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15358            || callingAppId == Process.NFC_UID || callingUid == 0) {
15359            // Always okay.
15360        } else if (callerApp == null || !callerApp.persistent) {
15361            try {
15362                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15363                        intent.getAction())) {
15364                    String msg = "Permission Denial: not allowed to send broadcast "
15365                            + intent.getAction() + " from pid="
15366                            + callingPid + ", uid=" + callingUid;
15367                    Slog.w(TAG, msg);
15368                    throw new SecurityException(msg);
15369                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15370                    // Special case for compatibility: we don't want apps to send this,
15371                    // but historically it has not been protected and apps may be using it
15372                    // to poke their own app widget.  So, instead of making it protected,
15373                    // just limit it to the caller.
15374                    if (callerApp == null) {
15375                        String msg = "Permission Denial: not allowed to send broadcast "
15376                                + intent.getAction() + " from unknown caller.";
15377                        Slog.w(TAG, msg);
15378                        throw new SecurityException(msg);
15379                    } else if (intent.getComponent() != null) {
15380                        // They are good enough to send to an explicit component...  verify
15381                        // it is being sent to the calling app.
15382                        if (!intent.getComponent().getPackageName().equals(
15383                                callerApp.info.packageName)) {
15384                            String msg = "Permission Denial: not allowed to send broadcast "
15385                                    + intent.getAction() + " to "
15386                                    + intent.getComponent().getPackageName() + " from "
15387                                    + callerApp.info.packageName;
15388                            Slog.w(TAG, msg);
15389                            throw new SecurityException(msg);
15390                        }
15391                    } else {
15392                        // Limit broadcast to their own package.
15393                        intent.setPackage(callerApp.info.packageName);
15394                    }
15395                }
15396            } catch (RemoteException e) {
15397                Slog.w(TAG, "Remote exception", e);
15398                return ActivityManager.BROADCAST_SUCCESS;
15399            }
15400        }
15401
15402        // Handle special intents: if this broadcast is from the package
15403        // manager about a package being removed, we need to remove all of
15404        // its activities from the history stack.
15405        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15406                intent.getAction());
15407        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15408                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15409                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15410                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15411                || uidRemoved) {
15412            if (checkComponentPermission(
15413                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15414                    callingPid, callingUid, -1, true)
15415                    == PackageManager.PERMISSION_GRANTED) {
15416                if (uidRemoved) {
15417                    final Bundle intentExtras = intent.getExtras();
15418                    final int uid = intentExtras != null
15419                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15420                    if (uid >= 0) {
15421                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15422                        synchronized (bs) {
15423                            bs.removeUidStatsLocked(uid);
15424                        }
15425                        mAppOpsService.uidRemoved(uid);
15426                    }
15427                } else {
15428                    // If resources are unavailable just force stop all
15429                    // those packages and flush the attribute cache as well.
15430                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15431                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15432                        if (list != null && (list.length > 0)) {
15433                            for (String pkg : list) {
15434                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15435                                        "storage unmount");
15436                            }
15437                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15438                            sendPackageBroadcastLocked(
15439                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15440                        }
15441                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15442                            intent.getAction())) {
15443                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15444                    } else {
15445                        Uri data = intent.getData();
15446                        String ssp;
15447                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15448                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15449                                    intent.getAction());
15450                            boolean fullUninstall = removed &&
15451                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15452                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15453                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15454                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15455                                        false, fullUninstall, userId,
15456                                        removed ? "pkg removed" : "pkg changed");
15457                            }
15458                            if (removed) {
15459                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15460                                        new String[] {ssp}, userId);
15461                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15462                                    mAppOpsService.packageRemoved(
15463                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15464
15465                                    // Remove all permissions granted from/to this package
15466                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15467                                }
15468                            }
15469                        }
15470                    }
15471                }
15472            } else {
15473                String msg = "Permission Denial: " + intent.getAction()
15474                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15475                        + ", uid=" + callingUid + ")"
15476                        + " requires "
15477                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15478                Slog.w(TAG, msg);
15479                throw new SecurityException(msg);
15480            }
15481
15482        // Special case for adding a package: by default turn on compatibility
15483        // mode.
15484        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15485            Uri data = intent.getData();
15486            String ssp;
15487            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15488                mCompatModePackages.handlePackageAddedLocked(ssp,
15489                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15490            }
15491        }
15492
15493        /*
15494         * If this is the time zone changed action, queue up a message that will reset the timezone
15495         * of all currently running processes. This message will get queued up before the broadcast
15496         * happens.
15497         */
15498        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15499            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15500        }
15501
15502        /*
15503         * If the user set the time, let all running processes know.
15504         */
15505        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15506            final int is24Hour = intent.getBooleanExtra(
15507                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15508            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15509            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15510            synchronized (stats) {
15511                stats.noteCurrentTimeChangedLocked();
15512            }
15513        }
15514
15515        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15516            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15517        }
15518
15519        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15520            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15521            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15522        }
15523
15524        // Add to the sticky list if requested.
15525        if (sticky) {
15526            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15527                    callingPid, callingUid)
15528                    != PackageManager.PERMISSION_GRANTED) {
15529                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15530                        + callingPid + ", uid=" + callingUid
15531                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15532                Slog.w(TAG, msg);
15533                throw new SecurityException(msg);
15534            }
15535            if (requiredPermission != null) {
15536                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15537                        + " and enforce permission " + requiredPermission);
15538                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15539            }
15540            if (intent.getComponent() != null) {
15541                throw new SecurityException(
15542                        "Sticky broadcasts can't target a specific component");
15543            }
15544            // We use userId directly here, since the "all" target is maintained
15545            // as a separate set of sticky broadcasts.
15546            if (userId != UserHandle.USER_ALL) {
15547                // But first, if this is not a broadcast to all users, then
15548                // make sure it doesn't conflict with an existing broadcast to
15549                // all users.
15550                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15551                        UserHandle.USER_ALL);
15552                if (stickies != null) {
15553                    ArrayList<Intent> list = stickies.get(intent.getAction());
15554                    if (list != null) {
15555                        int N = list.size();
15556                        int i;
15557                        for (i=0; i<N; i++) {
15558                            if (intent.filterEquals(list.get(i))) {
15559                                throw new IllegalArgumentException(
15560                                        "Sticky broadcast " + intent + " for user "
15561                                        + userId + " conflicts with existing global broadcast");
15562                            }
15563                        }
15564                    }
15565                }
15566            }
15567            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15568            if (stickies == null) {
15569                stickies = new ArrayMap<String, ArrayList<Intent>>();
15570                mStickyBroadcasts.put(userId, stickies);
15571            }
15572            ArrayList<Intent> list = stickies.get(intent.getAction());
15573            if (list == null) {
15574                list = new ArrayList<Intent>();
15575                stickies.put(intent.getAction(), list);
15576            }
15577            int N = list.size();
15578            int i;
15579            for (i=0; i<N; i++) {
15580                if (intent.filterEquals(list.get(i))) {
15581                    // This sticky already exists, replace it.
15582                    list.set(i, new Intent(intent));
15583                    break;
15584                }
15585            }
15586            if (i >= N) {
15587                list.add(new Intent(intent));
15588            }
15589        }
15590
15591        int[] users;
15592        if (userId == UserHandle.USER_ALL) {
15593            // Caller wants broadcast to go to all started users.
15594            users = mStartedUserArray;
15595        } else {
15596            // Caller wants broadcast to go to one specific user.
15597            users = new int[] {userId};
15598        }
15599
15600        // Figure out who all will receive this broadcast.
15601        List receivers = null;
15602        List<BroadcastFilter> registeredReceivers = null;
15603        // Need to resolve the intent to interested receivers...
15604        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15605                 == 0) {
15606            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15607        }
15608        if (intent.getComponent() == null) {
15609            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15610                // Query one target user at a time, excluding shell-restricted users
15611                UserManagerService ums = getUserManagerLocked();
15612                for (int i = 0; i < users.length; i++) {
15613                    if (ums.hasUserRestriction(
15614                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15615                        continue;
15616                    }
15617                    List<BroadcastFilter> registeredReceiversForUser =
15618                            mReceiverResolver.queryIntent(intent,
15619                                    resolvedType, false, users[i]);
15620                    if (registeredReceivers == null) {
15621                        registeredReceivers = registeredReceiversForUser;
15622                    } else if (registeredReceiversForUser != null) {
15623                        registeredReceivers.addAll(registeredReceiversForUser);
15624                    }
15625                }
15626            } else {
15627                registeredReceivers = mReceiverResolver.queryIntent(intent,
15628                        resolvedType, false, userId);
15629            }
15630        }
15631
15632        final boolean replacePending =
15633                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15634
15635        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15636                + " replacePending=" + replacePending);
15637
15638        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15639        if (!ordered && NR > 0) {
15640            // If we are not serializing this broadcast, then send the
15641            // registered receivers separately so they don't wait for the
15642            // components to be launched.
15643            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15644            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15645                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15646                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15647                    ordered, sticky, false, userId);
15648            if (DEBUG_BROADCAST) Slog.v(
15649                    TAG, "Enqueueing parallel broadcast " + r);
15650            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15651            if (!replaced) {
15652                queue.enqueueParallelBroadcastLocked(r);
15653                queue.scheduleBroadcastsLocked();
15654            }
15655            registeredReceivers = null;
15656            NR = 0;
15657        }
15658
15659        // Merge into one list.
15660        int ir = 0;
15661        if (receivers != null) {
15662            // A special case for PACKAGE_ADDED: do not allow the package
15663            // being added to see this broadcast.  This prevents them from
15664            // using this as a back door to get run as soon as they are
15665            // installed.  Maybe in the future we want to have a special install
15666            // broadcast or such for apps, but we'd like to deliberately make
15667            // this decision.
15668            String skipPackages[] = null;
15669            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15670                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15671                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15672                Uri data = intent.getData();
15673                if (data != null) {
15674                    String pkgName = data.getSchemeSpecificPart();
15675                    if (pkgName != null) {
15676                        skipPackages = new String[] { pkgName };
15677                    }
15678                }
15679            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15680                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15681            }
15682            if (skipPackages != null && (skipPackages.length > 0)) {
15683                for (String skipPackage : skipPackages) {
15684                    if (skipPackage != null) {
15685                        int NT = receivers.size();
15686                        for (int it=0; it<NT; it++) {
15687                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15688                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15689                                receivers.remove(it);
15690                                it--;
15691                                NT--;
15692                            }
15693                        }
15694                    }
15695                }
15696            }
15697
15698            int NT = receivers != null ? receivers.size() : 0;
15699            int it = 0;
15700            ResolveInfo curt = null;
15701            BroadcastFilter curr = null;
15702            while (it < NT && ir < NR) {
15703                if (curt == null) {
15704                    curt = (ResolveInfo)receivers.get(it);
15705                }
15706                if (curr == null) {
15707                    curr = registeredReceivers.get(ir);
15708                }
15709                if (curr.getPriority() >= curt.priority) {
15710                    // Insert this broadcast record into the final list.
15711                    receivers.add(it, curr);
15712                    ir++;
15713                    curr = null;
15714                    it++;
15715                    NT++;
15716                } else {
15717                    // Skip to the next ResolveInfo in the final list.
15718                    it++;
15719                    curt = null;
15720                }
15721            }
15722        }
15723        while (ir < NR) {
15724            if (receivers == null) {
15725                receivers = new ArrayList();
15726            }
15727            receivers.add(registeredReceivers.get(ir));
15728            ir++;
15729        }
15730
15731        if ((receivers != null && receivers.size() > 0)
15732                || resultTo != null) {
15733            BroadcastQueue queue = broadcastQueueForIntent(intent);
15734            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15735                    callerPackage, callingPid, callingUid, resolvedType,
15736                    requiredPermission, appOp, receivers, resultTo, resultCode,
15737                    resultData, map, ordered, sticky, false, userId);
15738            if (DEBUG_BROADCAST) Slog.v(
15739                    TAG, "Enqueueing ordered broadcast " + r
15740                    + ": prev had " + queue.mOrderedBroadcasts.size());
15741            if (DEBUG_BROADCAST) {
15742                int seq = r.intent.getIntExtra("seq", -1);
15743                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15744            }
15745            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15746            if (!replaced) {
15747                queue.enqueueOrderedBroadcastLocked(r);
15748                queue.scheduleBroadcastsLocked();
15749            }
15750        }
15751
15752        return ActivityManager.BROADCAST_SUCCESS;
15753    }
15754
15755    final Intent verifyBroadcastLocked(Intent intent) {
15756        // Refuse possible leaked file descriptors
15757        if (intent != null && intent.hasFileDescriptors() == true) {
15758            throw new IllegalArgumentException("File descriptors passed in Intent");
15759        }
15760
15761        int flags = intent.getFlags();
15762
15763        if (!mProcessesReady) {
15764            // if the caller really truly claims to know what they're doing, go
15765            // ahead and allow the broadcast without launching any receivers
15766            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15767                intent = new Intent(intent);
15768                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15769            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15770                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15771                        + " before boot completion");
15772                throw new IllegalStateException("Cannot broadcast before boot completed");
15773            }
15774        }
15775
15776        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15777            throw new IllegalArgumentException(
15778                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15779        }
15780
15781        return intent;
15782    }
15783
15784    public final int broadcastIntent(IApplicationThread caller,
15785            Intent intent, String resolvedType, IIntentReceiver resultTo,
15786            int resultCode, String resultData, Bundle map,
15787            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15788        enforceNotIsolatedCaller("broadcastIntent");
15789        synchronized(this) {
15790            intent = verifyBroadcastLocked(intent);
15791
15792            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15793            final int callingPid = Binder.getCallingPid();
15794            final int callingUid = Binder.getCallingUid();
15795            final long origId = Binder.clearCallingIdentity();
15796            int res = broadcastIntentLocked(callerApp,
15797                    callerApp != null ? callerApp.info.packageName : null,
15798                    intent, resolvedType, resultTo,
15799                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15800                    callingPid, callingUid, userId);
15801            Binder.restoreCallingIdentity(origId);
15802            return res;
15803        }
15804    }
15805
15806    int broadcastIntentInPackage(String packageName, int uid,
15807            Intent intent, String resolvedType, IIntentReceiver resultTo,
15808            int resultCode, String resultData, Bundle map,
15809            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15810        synchronized(this) {
15811            intent = verifyBroadcastLocked(intent);
15812
15813            final long origId = Binder.clearCallingIdentity();
15814            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15815                    resultTo, resultCode, resultData, map, requiredPermission,
15816                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15817            Binder.restoreCallingIdentity(origId);
15818            return res;
15819        }
15820    }
15821
15822    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15823        // Refuse possible leaked file descriptors
15824        if (intent != null && intent.hasFileDescriptors() == true) {
15825            throw new IllegalArgumentException("File descriptors passed in Intent");
15826        }
15827
15828        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15829                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15830
15831        synchronized(this) {
15832            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15833                    != PackageManager.PERMISSION_GRANTED) {
15834                String msg = "Permission Denial: unbroadcastIntent() from pid="
15835                        + Binder.getCallingPid()
15836                        + ", uid=" + Binder.getCallingUid()
15837                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15838                Slog.w(TAG, msg);
15839                throw new SecurityException(msg);
15840            }
15841            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15842            if (stickies != null) {
15843                ArrayList<Intent> list = stickies.get(intent.getAction());
15844                if (list != null) {
15845                    int N = list.size();
15846                    int i;
15847                    for (i=0; i<N; i++) {
15848                        if (intent.filterEquals(list.get(i))) {
15849                            list.remove(i);
15850                            break;
15851                        }
15852                    }
15853                    if (list.size() <= 0) {
15854                        stickies.remove(intent.getAction());
15855                    }
15856                }
15857                if (stickies.size() <= 0) {
15858                    mStickyBroadcasts.remove(userId);
15859                }
15860            }
15861        }
15862    }
15863
15864    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15865            String resultData, Bundle resultExtras, boolean resultAbort) {
15866        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15867        if (r == null) {
15868            Slog.w(TAG, "finishReceiver called but not found on queue");
15869            return false;
15870        }
15871
15872        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15873    }
15874
15875    void backgroundServicesFinishedLocked(int userId) {
15876        for (BroadcastQueue queue : mBroadcastQueues) {
15877            queue.backgroundServicesFinishedLocked(userId);
15878        }
15879    }
15880
15881    public void finishReceiver(IBinder who, int resultCode, String resultData,
15882            Bundle resultExtras, boolean resultAbort) {
15883        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15884
15885        // Refuse possible leaked file descriptors
15886        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15887            throw new IllegalArgumentException("File descriptors passed in Bundle");
15888        }
15889
15890        final long origId = Binder.clearCallingIdentity();
15891        try {
15892            boolean doNext = false;
15893            BroadcastRecord r;
15894
15895            synchronized(this) {
15896                r = broadcastRecordForReceiverLocked(who);
15897                if (r != null) {
15898                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15899                        resultData, resultExtras, resultAbort, true);
15900                }
15901            }
15902
15903            if (doNext) {
15904                r.queue.processNextBroadcast(false);
15905            }
15906            trimApplications();
15907        } finally {
15908            Binder.restoreCallingIdentity(origId);
15909        }
15910    }
15911
15912    // =========================================================
15913    // INSTRUMENTATION
15914    // =========================================================
15915
15916    public boolean startInstrumentation(ComponentName className,
15917            String profileFile, int flags, Bundle arguments,
15918            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15919            int userId, String abiOverride) {
15920        enforceNotIsolatedCaller("startInstrumentation");
15921        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15922                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15923        // Refuse possible leaked file descriptors
15924        if (arguments != null && arguments.hasFileDescriptors()) {
15925            throw new IllegalArgumentException("File descriptors passed in Bundle");
15926        }
15927
15928        synchronized(this) {
15929            InstrumentationInfo ii = null;
15930            ApplicationInfo ai = null;
15931            try {
15932                ii = mContext.getPackageManager().getInstrumentationInfo(
15933                    className, STOCK_PM_FLAGS);
15934                ai = AppGlobals.getPackageManager().getApplicationInfo(
15935                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15936            } catch (PackageManager.NameNotFoundException e) {
15937            } catch (RemoteException e) {
15938            }
15939            if (ii == null) {
15940                reportStartInstrumentationFailure(watcher, className,
15941                        "Unable to find instrumentation info for: " + className);
15942                return false;
15943            }
15944            if (ai == null) {
15945                reportStartInstrumentationFailure(watcher, className,
15946                        "Unable to find instrumentation target package: " + ii.targetPackage);
15947                return false;
15948            }
15949
15950            int match = mContext.getPackageManager().checkSignatures(
15951                    ii.targetPackage, ii.packageName);
15952            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15953                String msg = "Permission Denial: starting instrumentation "
15954                        + className + " from pid="
15955                        + Binder.getCallingPid()
15956                        + ", uid=" + Binder.getCallingPid()
15957                        + " not allowed because package " + ii.packageName
15958                        + " does not have a signature matching the target "
15959                        + ii.targetPackage;
15960                reportStartInstrumentationFailure(watcher, className, msg);
15961                throw new SecurityException(msg);
15962            }
15963
15964            final long origId = Binder.clearCallingIdentity();
15965            // Instrumentation can kill and relaunch even persistent processes
15966            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15967                    "start instr");
15968            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15969            app.instrumentationClass = className;
15970            app.instrumentationInfo = ai;
15971            app.instrumentationProfileFile = profileFile;
15972            app.instrumentationArguments = arguments;
15973            app.instrumentationWatcher = watcher;
15974            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15975            app.instrumentationResultClass = className;
15976            Binder.restoreCallingIdentity(origId);
15977        }
15978
15979        return true;
15980    }
15981
15982    /**
15983     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15984     * error to the logs, but if somebody is watching, send the report there too.  This enables
15985     * the "am" command to report errors with more information.
15986     *
15987     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15988     * @param cn The component name of the instrumentation.
15989     * @param report The error report.
15990     */
15991    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15992            ComponentName cn, String report) {
15993        Slog.w(TAG, report);
15994        try {
15995            if (watcher != null) {
15996                Bundle results = new Bundle();
15997                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15998                results.putString("Error", report);
15999                watcher.instrumentationStatus(cn, -1, results);
16000            }
16001        } catch (RemoteException e) {
16002            Slog.w(TAG, e);
16003        }
16004    }
16005
16006    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16007        if (app.instrumentationWatcher != null) {
16008            try {
16009                // NOTE:  IInstrumentationWatcher *must* be oneway here
16010                app.instrumentationWatcher.instrumentationFinished(
16011                    app.instrumentationClass,
16012                    resultCode,
16013                    results);
16014            } catch (RemoteException e) {
16015            }
16016        }
16017        if (app.instrumentationUiAutomationConnection != null) {
16018            try {
16019                app.instrumentationUiAutomationConnection.shutdown();
16020            } catch (RemoteException re) {
16021                /* ignore */
16022            }
16023            // Only a UiAutomation can set this flag and now that
16024            // it is finished we make sure it is reset to its default.
16025            mUserIsMonkey = false;
16026        }
16027        app.instrumentationWatcher = null;
16028        app.instrumentationUiAutomationConnection = null;
16029        app.instrumentationClass = null;
16030        app.instrumentationInfo = null;
16031        app.instrumentationProfileFile = null;
16032        app.instrumentationArguments = null;
16033
16034        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16035                "finished inst");
16036    }
16037
16038    public void finishInstrumentation(IApplicationThread target,
16039            int resultCode, Bundle results) {
16040        int userId = UserHandle.getCallingUserId();
16041        // Refuse possible leaked file descriptors
16042        if (results != null && results.hasFileDescriptors()) {
16043            throw new IllegalArgumentException("File descriptors passed in Intent");
16044        }
16045
16046        synchronized(this) {
16047            ProcessRecord app = getRecordForAppLocked(target);
16048            if (app == null) {
16049                Slog.w(TAG, "finishInstrumentation: no app for " + target);
16050                return;
16051            }
16052            final long origId = Binder.clearCallingIdentity();
16053            finishInstrumentationLocked(app, resultCode, results);
16054            Binder.restoreCallingIdentity(origId);
16055        }
16056    }
16057
16058    // =========================================================
16059    // CONFIGURATION
16060    // =========================================================
16061
16062    public ConfigurationInfo getDeviceConfigurationInfo() {
16063        ConfigurationInfo config = new ConfigurationInfo();
16064        synchronized (this) {
16065            config.reqTouchScreen = mConfiguration.touchscreen;
16066            config.reqKeyboardType = mConfiguration.keyboard;
16067            config.reqNavigation = mConfiguration.navigation;
16068            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16069                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16070                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16071            }
16072            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16073                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16074                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16075            }
16076            config.reqGlEsVersion = GL_ES_VERSION;
16077        }
16078        return config;
16079    }
16080
16081    ActivityStack getFocusedStack() {
16082        return mStackSupervisor.getFocusedStack();
16083    }
16084
16085    public Configuration getConfiguration() {
16086        Configuration ci;
16087        synchronized(this) {
16088            ci = new Configuration(mConfiguration);
16089        }
16090        return ci;
16091    }
16092
16093    public void updatePersistentConfiguration(Configuration values) {
16094        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16095                "updateConfiguration()");
16096        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16097                "updateConfiguration()");
16098        if (values == null) {
16099            throw new NullPointerException("Configuration must not be null");
16100        }
16101
16102        synchronized(this) {
16103            final long origId = Binder.clearCallingIdentity();
16104            updateConfigurationLocked(values, null, true, false);
16105            Binder.restoreCallingIdentity(origId);
16106        }
16107    }
16108
16109    public void updateConfiguration(Configuration values) {
16110        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16111                "updateConfiguration()");
16112
16113        synchronized(this) {
16114            if (values == null && mWindowManager != null) {
16115                // sentinel: fetch the current configuration from the window manager
16116                values = mWindowManager.computeNewConfiguration();
16117            }
16118
16119            if (mWindowManager != null) {
16120                mProcessList.applyDisplaySize(mWindowManager);
16121            }
16122
16123            final long origId = Binder.clearCallingIdentity();
16124            if (values != null) {
16125                Settings.System.clearConfiguration(values);
16126            }
16127            updateConfigurationLocked(values, null, false, false);
16128            Binder.restoreCallingIdentity(origId);
16129        }
16130    }
16131
16132    /**
16133     * Do either or both things: (1) change the current configuration, and (2)
16134     * make sure the given activity is running with the (now) current
16135     * configuration.  Returns true if the activity has been left running, or
16136     * false if <var>starting</var> is being destroyed to match the new
16137     * configuration.
16138     * @param persistent TODO
16139     */
16140    boolean updateConfigurationLocked(Configuration values,
16141            ActivityRecord starting, boolean persistent, boolean initLocale) {
16142        int changes = 0;
16143
16144        if (values != null) {
16145            Configuration newConfig = new Configuration(mConfiguration);
16146            changes = newConfig.updateFrom(values);
16147            if (changes != 0) {
16148                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16149                    Slog.i(TAG, "Updating configuration to: " + values);
16150                }
16151
16152                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16153
16154                if (values.locale != null && !initLocale) {
16155                    saveLocaleLocked(values.locale,
16156                                     !values.locale.equals(mConfiguration.locale),
16157                                     values.userSetLocale);
16158                }
16159
16160                mConfigurationSeq++;
16161                if (mConfigurationSeq <= 0) {
16162                    mConfigurationSeq = 1;
16163                }
16164                newConfig.seq = mConfigurationSeq;
16165                mConfiguration = newConfig;
16166                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16167                mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16168                //mUsageStatsService.noteStartConfig(newConfig);
16169
16170                final Configuration configCopy = new Configuration(mConfiguration);
16171
16172                // TODO: If our config changes, should we auto dismiss any currently
16173                // showing dialogs?
16174                mShowDialogs = shouldShowDialogs(newConfig);
16175
16176                AttributeCache ac = AttributeCache.instance();
16177                if (ac != null) {
16178                    ac.updateConfiguration(configCopy);
16179                }
16180
16181                // Make sure all resources in our process are updated
16182                // right now, so that anyone who is going to retrieve
16183                // resource values after we return will be sure to get
16184                // the new ones.  This is especially important during
16185                // boot, where the first config change needs to guarantee
16186                // all resources have that config before following boot
16187                // code is executed.
16188                mSystemThread.applyConfigurationToResources(configCopy);
16189
16190                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16191                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16192                    msg.obj = new Configuration(configCopy);
16193                    mHandler.sendMessage(msg);
16194                }
16195
16196                for (int i=mLruProcesses.size()-1; i>=0; i--) {
16197                    ProcessRecord app = mLruProcesses.get(i);
16198                    try {
16199                        if (app.thread != null) {
16200                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16201                                    + app.processName + " new config " + mConfiguration);
16202                            app.thread.scheduleConfigurationChanged(configCopy);
16203                        }
16204                    } catch (Exception e) {
16205                    }
16206                }
16207                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16208                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16209                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
16210                        | Intent.FLAG_RECEIVER_FOREGROUND);
16211                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16212                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
16213                        Process.SYSTEM_UID, UserHandle.USER_ALL);
16214                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16215                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16216                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16217                    broadcastIntentLocked(null, null, intent,
16218                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16219                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16220                }
16221            }
16222        }
16223
16224        boolean kept = true;
16225        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16226        // mainStack is null during startup.
16227        if (mainStack != null) {
16228            if (changes != 0 && starting == null) {
16229                // If the configuration changed, and the caller is not already
16230                // in the process of starting an activity, then find the top
16231                // activity to check if its configuration needs to change.
16232                starting = mainStack.topRunningActivityLocked(null);
16233            }
16234
16235            if (starting != null) {
16236                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16237                // And we need to make sure at this point that all other activities
16238                // are made visible with the correct configuration.
16239                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16240            }
16241        }
16242
16243        if (values != null && mWindowManager != null) {
16244            mWindowManager.setNewConfiguration(mConfiguration);
16245        }
16246
16247        return kept;
16248    }
16249
16250    /**
16251     * Decide based on the configuration whether we should shouw the ANR,
16252     * crash, etc dialogs.  The idea is that if there is no affordnace to
16253     * press the on-screen buttons, we shouldn't show the dialog.
16254     *
16255     * A thought: SystemUI might also want to get told about this, the Power
16256     * dialog / global actions also might want different behaviors.
16257     */
16258    private static final boolean shouldShowDialogs(Configuration config) {
16259        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16260                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16261    }
16262
16263    /**
16264     * Save the locale.  You must be inside a synchronized (this) block.
16265     */
16266    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16267        if(isDiff) {
16268            SystemProperties.set("user.language", l.getLanguage());
16269            SystemProperties.set("user.region", l.getCountry());
16270        }
16271
16272        if(isPersist) {
16273            SystemProperties.set("persist.sys.language", l.getLanguage());
16274            SystemProperties.set("persist.sys.country", l.getCountry());
16275            SystemProperties.set("persist.sys.localevar", l.getVariant());
16276
16277            mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16278        }
16279    }
16280
16281    @Override
16282    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16283        synchronized (this) {
16284            ActivityRecord srec = ActivityRecord.forToken(token);
16285            if (srec.task != null && srec.task.stack != null) {
16286                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16287            }
16288        }
16289        return false;
16290    }
16291
16292    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16293            Intent resultData) {
16294
16295        synchronized (this) {
16296            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16297            if (stack != null) {
16298                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16299            }
16300            return false;
16301        }
16302    }
16303
16304    public int getLaunchedFromUid(IBinder activityToken) {
16305        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16306        if (srec == null) {
16307            return -1;
16308        }
16309        return srec.launchedFromUid;
16310    }
16311
16312    public String getLaunchedFromPackage(IBinder activityToken) {
16313        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16314        if (srec == null) {
16315            return null;
16316        }
16317        return srec.launchedFromPackage;
16318    }
16319
16320    // =========================================================
16321    // LIFETIME MANAGEMENT
16322    // =========================================================
16323
16324    // Returns which broadcast queue the app is the current [or imminent] receiver
16325    // on, or 'null' if the app is not an active broadcast recipient.
16326    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16327        BroadcastRecord r = app.curReceiver;
16328        if (r != null) {
16329            return r.queue;
16330        }
16331
16332        // It's not the current receiver, but it might be starting up to become one
16333        synchronized (this) {
16334            for (BroadcastQueue queue : mBroadcastQueues) {
16335                r = queue.mPendingBroadcast;
16336                if (r != null && r.curApp == app) {
16337                    // found it; report which queue it's in
16338                    return queue;
16339                }
16340            }
16341        }
16342
16343        return null;
16344    }
16345
16346    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16347            boolean doingAll, long now) {
16348        if (mAdjSeq == app.adjSeq) {
16349            // This adjustment has already been computed.
16350            return app.curRawAdj;
16351        }
16352
16353        if (app.thread == null) {
16354            app.adjSeq = mAdjSeq;
16355            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16356            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16357            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16358        }
16359
16360        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16361        app.adjSource = null;
16362        app.adjTarget = null;
16363        app.empty = false;
16364        app.cached = false;
16365
16366        final int activitiesSize = app.activities.size();
16367
16368        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16369            // The max adjustment doesn't allow this app to be anything
16370            // below foreground, so it is not worth doing work for it.
16371            app.adjType = "fixed";
16372            app.adjSeq = mAdjSeq;
16373            app.curRawAdj = app.maxAdj;
16374            app.foregroundActivities = false;
16375            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16376            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16377            // System processes can do UI, and when they do we want to have
16378            // them trim their memory after the user leaves the UI.  To
16379            // facilitate this, here we need to determine whether or not it
16380            // is currently showing UI.
16381            app.systemNoUi = true;
16382            if (app == TOP_APP) {
16383                app.systemNoUi = false;
16384            } else if (activitiesSize > 0) {
16385                for (int j = 0; j < activitiesSize; j++) {
16386                    final ActivityRecord r = app.activities.get(j);
16387                    if (r.visible) {
16388                        app.systemNoUi = false;
16389                    }
16390                }
16391            }
16392            if (!app.systemNoUi) {
16393                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16394            }
16395            return (app.curAdj=app.maxAdj);
16396        }
16397
16398        app.systemNoUi = false;
16399
16400        // Determine the importance of the process, starting with most
16401        // important to least, and assign an appropriate OOM adjustment.
16402        int adj;
16403        int schedGroup;
16404        int procState;
16405        boolean foregroundActivities = false;
16406        BroadcastQueue queue;
16407        if (app == TOP_APP) {
16408            // The last app on the list is the foreground app.
16409            adj = ProcessList.FOREGROUND_APP_ADJ;
16410            schedGroup = Process.THREAD_GROUP_DEFAULT;
16411            app.adjType = "top-activity";
16412            foregroundActivities = true;
16413            procState = ActivityManager.PROCESS_STATE_TOP;
16414        } else if (app.instrumentationClass != null) {
16415            // Don't want to kill running instrumentation.
16416            adj = ProcessList.FOREGROUND_APP_ADJ;
16417            schedGroup = Process.THREAD_GROUP_DEFAULT;
16418            app.adjType = "instrumentation";
16419            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16420        } else if ((queue = isReceivingBroadcast(app)) != null) {
16421            // An app that is currently receiving a broadcast also
16422            // counts as being in the foreground for OOM killer purposes.
16423            // It's placed in a sched group based on the nature of the
16424            // broadcast as reflected by which queue it's active in.
16425            adj = ProcessList.FOREGROUND_APP_ADJ;
16426            schedGroup = (queue == mFgBroadcastQueue)
16427                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16428            app.adjType = "broadcast";
16429            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16430        } else if (app.executingServices.size() > 0) {
16431            // An app that is currently executing a service callback also
16432            // counts as being in the foreground.
16433            adj = ProcessList.FOREGROUND_APP_ADJ;
16434            schedGroup = app.execServicesFg ?
16435                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16436            app.adjType = "exec-service";
16437            procState = ActivityManager.PROCESS_STATE_SERVICE;
16438            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16439        } else {
16440            // As far as we know the process is empty.  We may change our mind later.
16441            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16442            // At this point we don't actually know the adjustment.  Use the cached adj
16443            // value that the caller wants us to.
16444            adj = cachedAdj;
16445            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16446            app.cached = true;
16447            app.empty = true;
16448            app.adjType = "cch-empty";
16449        }
16450
16451        // Examine all activities if not already foreground.
16452        if (!foregroundActivities && activitiesSize > 0) {
16453            for (int j = 0; j < activitiesSize; j++) {
16454                final ActivityRecord r = app.activities.get(j);
16455                if (r.app != app) {
16456                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16457                            + app + "?!?");
16458                    continue;
16459                }
16460                if (r.visible) {
16461                    // App has a visible activity; only upgrade adjustment.
16462                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16463                        adj = ProcessList.VISIBLE_APP_ADJ;
16464                        app.adjType = "visible";
16465                    }
16466                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16467                        procState = ActivityManager.PROCESS_STATE_TOP;
16468                    }
16469                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16470                    app.cached = false;
16471                    app.empty = false;
16472                    foregroundActivities = true;
16473                    break;
16474                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16475                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16476                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16477                        app.adjType = "pausing";
16478                    }
16479                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16480                        procState = ActivityManager.PROCESS_STATE_TOP;
16481                    }
16482                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16483                    app.cached = false;
16484                    app.empty = false;
16485                    foregroundActivities = true;
16486                } else if (r.state == ActivityState.STOPPING) {
16487                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16488                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16489                        app.adjType = "stopping";
16490                    }
16491                    // For the process state, we will at this point consider the
16492                    // process to be cached.  It will be cached either as an activity
16493                    // or empty depending on whether the activity is finishing.  We do
16494                    // this so that we can treat the process as cached for purposes of
16495                    // memory trimming (determing current memory level, trim command to
16496                    // send to process) since there can be an arbitrary number of stopping
16497                    // processes and they should soon all go into the cached state.
16498                    if (!r.finishing) {
16499                        if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16500                            procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16501                        }
16502                    }
16503                    app.cached = false;
16504                    app.empty = false;
16505                    foregroundActivities = true;
16506                } else {
16507                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16508                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16509                        app.adjType = "cch-act";
16510                    }
16511                }
16512            }
16513        }
16514
16515        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16516            if (app.foregroundServices) {
16517                // The user is aware of this app, so make it visible.
16518                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16519                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16520                app.cached = false;
16521                app.adjType = "fg-service";
16522                schedGroup = Process.THREAD_GROUP_DEFAULT;
16523            } else if (app.forcingToForeground != null) {
16524                // The user is aware of this app, so make it visible.
16525                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16526                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16527                app.cached = false;
16528                app.adjType = "force-fg";
16529                app.adjSource = app.forcingToForeground;
16530                schedGroup = Process.THREAD_GROUP_DEFAULT;
16531            }
16532        }
16533
16534        if (app == mHeavyWeightProcess) {
16535            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16536                // We don't want to kill the current heavy-weight process.
16537                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16538                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16539                app.cached = false;
16540                app.adjType = "heavy";
16541            }
16542            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16543                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16544            }
16545        }
16546
16547        if (app == mHomeProcess) {
16548            if (adj > ProcessList.HOME_APP_ADJ) {
16549                // This process is hosting what we currently consider to be the
16550                // home app, so we don't want to let it go into the background.
16551                adj = ProcessList.HOME_APP_ADJ;
16552                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16553                app.cached = false;
16554                app.adjType = "home";
16555            }
16556            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16557                procState = ActivityManager.PROCESS_STATE_HOME;
16558            }
16559        }
16560
16561        if (app == mPreviousProcess && app.activities.size() > 0) {
16562            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16563                // This was the previous process that showed UI to the user.
16564                // We want to try to keep it around more aggressively, to give
16565                // a good experience around switching between two apps.
16566                adj = ProcessList.PREVIOUS_APP_ADJ;
16567                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16568                app.cached = false;
16569                app.adjType = "previous";
16570            }
16571            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16572                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16573            }
16574        }
16575
16576        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16577                + " reason=" + app.adjType);
16578
16579        // By default, we use the computed adjustment.  It may be changed if
16580        // there are applications dependent on our services or providers, but
16581        // this gives us a baseline and makes sure we don't get into an
16582        // infinite recursion.
16583        app.adjSeq = mAdjSeq;
16584        app.curRawAdj = adj;
16585        app.hasStartedServices = false;
16586
16587        if (mBackupTarget != null && app == mBackupTarget.app) {
16588            // If possible we want to avoid killing apps while they're being backed up
16589            if (adj > ProcessList.BACKUP_APP_ADJ) {
16590                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16591                adj = ProcessList.BACKUP_APP_ADJ;
16592                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16593                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16594                }
16595                app.adjType = "backup";
16596                app.cached = false;
16597            }
16598            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16599                procState = ActivityManager.PROCESS_STATE_BACKUP;
16600            }
16601        }
16602
16603        boolean mayBeTop = false;
16604
16605        for (int is = app.services.size()-1;
16606                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16607                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16608                        || procState > ActivityManager.PROCESS_STATE_TOP);
16609                is--) {
16610            ServiceRecord s = app.services.valueAt(is);
16611            if (s.startRequested) {
16612                app.hasStartedServices = true;
16613                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16614                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16615                }
16616                if (app.hasShownUi && app != mHomeProcess) {
16617                    // If this process has shown some UI, let it immediately
16618                    // go to the LRU list because it may be pretty heavy with
16619                    // UI stuff.  We'll tag it with a label just to help
16620                    // debug and understand what is going on.
16621                    if (adj > ProcessList.SERVICE_ADJ) {
16622                        app.adjType = "cch-started-ui-services";
16623                    }
16624                } else {
16625                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16626                        // This service has seen some activity within
16627                        // recent memory, so we will keep its process ahead
16628                        // of the background processes.
16629                        if (adj > ProcessList.SERVICE_ADJ) {
16630                            adj = ProcessList.SERVICE_ADJ;
16631                            app.adjType = "started-services";
16632                            app.cached = false;
16633                        }
16634                    }
16635                    // If we have let the service slide into the background
16636                    // state, still have some text describing what it is doing
16637                    // even though the service no longer has an impact.
16638                    if (adj > ProcessList.SERVICE_ADJ) {
16639                        app.adjType = "cch-started-services";
16640                    }
16641                }
16642            }
16643            for (int conni = s.connections.size()-1;
16644                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16645                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16646                            || procState > ActivityManager.PROCESS_STATE_TOP);
16647                    conni--) {
16648                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16649                for (int i = 0;
16650                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16651                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16652                                || procState > ActivityManager.PROCESS_STATE_TOP);
16653                        i++) {
16654                    // XXX should compute this based on the max of
16655                    // all connected clients.
16656                    ConnectionRecord cr = clist.get(i);
16657                    if (cr.binding.client == app) {
16658                        // Binding to ourself is not interesting.
16659                        continue;
16660                    }
16661                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16662                        ProcessRecord client = cr.binding.client;
16663                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16664                                TOP_APP, doingAll, now);
16665                        int clientProcState = client.curProcState;
16666                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16667                            // If the other app is cached for any reason, for purposes here
16668                            // we are going to consider it empty.  The specific cached state
16669                            // doesn't propagate except under certain conditions.
16670                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16671                        }
16672                        String adjType = null;
16673                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16674                            // Not doing bind OOM management, so treat
16675                            // this guy more like a started service.
16676                            if (app.hasShownUi && app != mHomeProcess) {
16677                                // If this process has shown some UI, let it immediately
16678                                // go to the LRU list because it may be pretty heavy with
16679                                // UI stuff.  We'll tag it with a label just to help
16680                                // debug and understand what is going on.
16681                                if (adj > clientAdj) {
16682                                    adjType = "cch-bound-ui-services";
16683                                }
16684                                app.cached = false;
16685                                clientAdj = adj;
16686                                clientProcState = procState;
16687                            } else {
16688                                if (now >= (s.lastActivity
16689                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16690                                    // This service has not seen activity within
16691                                    // recent memory, so allow it to drop to the
16692                                    // LRU list if there is no other reason to keep
16693                                    // it around.  We'll also tag it with a label just
16694                                    // to help debug and undertand what is going on.
16695                                    if (adj > clientAdj) {
16696                                        adjType = "cch-bound-services";
16697                                    }
16698                                    clientAdj = adj;
16699                                }
16700                            }
16701                        }
16702                        if (adj > clientAdj) {
16703                            // If this process has recently shown UI, and
16704                            // the process that is binding to it is less
16705                            // important than being visible, then we don't
16706                            // care about the binding as much as we care
16707                            // about letting this process get into the LRU
16708                            // list to be killed and restarted if needed for
16709                            // memory.
16710                            if (app.hasShownUi && app != mHomeProcess
16711                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16712                                adjType = "cch-bound-ui-services";
16713                            } else {
16714                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16715                                        |Context.BIND_IMPORTANT)) != 0) {
16716                                    adj = clientAdj;
16717                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16718                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16719                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16720                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16721                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16722                                    adj = clientAdj;
16723                                } else {
16724                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16725                                        adj = ProcessList.VISIBLE_APP_ADJ;
16726                                    }
16727                                }
16728                                if (!client.cached) {
16729                                    app.cached = false;
16730                                }
16731                                adjType = "service";
16732                            }
16733                        }
16734                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16735                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16736                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16737                            }
16738                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16739                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16740                                    // Special handling of clients who are in the top state.
16741                                    // We *may* want to consider this process to be in the
16742                                    // top state as well, but only if there is not another
16743                                    // reason for it to be running.  Being on the top is a
16744                                    // special state, meaning you are specifically running
16745                                    // for the current top app.  If the process is already
16746                                    // running in the background for some other reason, it
16747                                    // is more important to continue considering it to be
16748                                    // in the background state.
16749                                    mayBeTop = true;
16750                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16751                                } else {
16752                                    // Special handling for above-top states (persistent
16753                                    // processes).  These should not bring the current process
16754                                    // into the top state, since they are not on top.  Instead
16755                                    // give them the best state after that.
16756                                    clientProcState =
16757                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16758                                }
16759                            }
16760                        } else {
16761                            if (clientProcState <
16762                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16763                                clientProcState =
16764                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16765                            }
16766                        }
16767                        if (procState > clientProcState) {
16768                            procState = clientProcState;
16769                        }
16770                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16771                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16772                            app.pendingUiClean = true;
16773                        }
16774                        if (adjType != null) {
16775                            app.adjType = adjType;
16776                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16777                                    .REASON_SERVICE_IN_USE;
16778                            app.adjSource = cr.binding.client;
16779                            app.adjSourceProcState = clientProcState;
16780                            app.adjTarget = s.name;
16781                        }
16782                    }
16783                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16784                        app.treatLikeActivity = true;
16785                    }
16786                    final ActivityRecord a = cr.activity;
16787                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16788                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16789                                (a.visible || a.state == ActivityState.RESUMED
16790                                 || a.state == ActivityState.PAUSING)) {
16791                            adj = ProcessList.FOREGROUND_APP_ADJ;
16792                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16793                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16794                            }
16795                            app.cached = false;
16796                            app.adjType = "service";
16797                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16798                                    .REASON_SERVICE_IN_USE;
16799                            app.adjSource = a;
16800                            app.adjSourceProcState = procState;
16801                            app.adjTarget = s.name;
16802                        }
16803                    }
16804                }
16805            }
16806        }
16807
16808        for (int provi = app.pubProviders.size()-1;
16809                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16810                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16811                        || procState > ActivityManager.PROCESS_STATE_TOP);
16812                provi--) {
16813            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16814            for (int i = cpr.connections.size()-1;
16815                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16816                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16817                            || procState > ActivityManager.PROCESS_STATE_TOP);
16818                    i--) {
16819                ContentProviderConnection conn = cpr.connections.get(i);
16820                ProcessRecord client = conn.client;
16821                if (client == app) {
16822                    // Being our own client is not interesting.
16823                    continue;
16824                }
16825                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16826                int clientProcState = client.curProcState;
16827                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16828                    // If the other app is cached for any reason, for purposes here
16829                    // we are going to consider it empty.
16830                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16831                }
16832                if (adj > clientAdj) {
16833                    if (app.hasShownUi && app != mHomeProcess
16834                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16835                        app.adjType = "cch-ui-provider";
16836                    } else {
16837                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16838                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16839                        app.adjType = "provider";
16840                    }
16841                    app.cached &= client.cached;
16842                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16843                            .REASON_PROVIDER_IN_USE;
16844                    app.adjSource = client;
16845                    app.adjSourceProcState = clientProcState;
16846                    app.adjTarget = cpr.name;
16847                }
16848                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16849                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16850                        // Special handling of clients who are in the top state.
16851                        // We *may* want to consider this process to be in the
16852                        // top state as well, but only if there is not another
16853                        // reason for it to be running.  Being on the top is a
16854                        // special state, meaning you are specifically running
16855                        // for the current top app.  If the process is already
16856                        // running in the background for some other reason, it
16857                        // is more important to continue considering it to be
16858                        // in the background state.
16859                        mayBeTop = true;
16860                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16861                    } else {
16862                        // Special handling for above-top states (persistent
16863                        // processes).  These should not bring the current process
16864                        // into the top state, since they are not on top.  Instead
16865                        // give them the best state after that.
16866                        clientProcState =
16867                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16868                    }
16869                }
16870                if (procState > clientProcState) {
16871                    procState = clientProcState;
16872                }
16873                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16874                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16875                }
16876            }
16877            // If the provider has external (non-framework) process
16878            // dependencies, ensure that its adjustment is at least
16879            // FOREGROUND_APP_ADJ.
16880            if (cpr.hasExternalProcessHandles()) {
16881                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16882                    adj = ProcessList.FOREGROUND_APP_ADJ;
16883                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16884                    app.cached = false;
16885                    app.adjType = "provider";
16886                    app.adjTarget = cpr.name;
16887                }
16888                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16889                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16890                }
16891            }
16892        }
16893
16894        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16895            // A client of one of our services or providers is in the top state.  We
16896            // *may* want to be in the top state, but not if we are already running in
16897            // the background for some other reason.  For the decision here, we are going
16898            // to pick out a few specific states that we want to remain in when a client
16899            // is top (states that tend to be longer-term) and otherwise allow it to go
16900            // to the top state.
16901            switch (procState) {
16902                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16903                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16904                case ActivityManager.PROCESS_STATE_SERVICE:
16905                    // These all are longer-term states, so pull them up to the top
16906                    // of the background states, but not all the way to the top state.
16907                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16908                    break;
16909                default:
16910                    // Otherwise, top is a better choice, so take it.
16911                    procState = ActivityManager.PROCESS_STATE_TOP;
16912                    break;
16913            }
16914        }
16915
16916        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16917            if (app.hasClientActivities) {
16918                // This is a cached process, but with client activities.  Mark it so.
16919                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16920                app.adjType = "cch-client-act";
16921            } else if (app.treatLikeActivity) {
16922                // This is a cached process, but somebody wants us to treat it like it has
16923                // an activity, okay!
16924                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16925                app.adjType = "cch-as-act";
16926            }
16927        }
16928
16929        if (adj == ProcessList.SERVICE_ADJ) {
16930            if (doingAll) {
16931                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16932                mNewNumServiceProcs++;
16933                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16934                if (!app.serviceb) {
16935                    // This service isn't far enough down on the LRU list to
16936                    // normally be a B service, but if we are low on RAM and it
16937                    // is large we want to force it down since we would prefer to
16938                    // keep launcher over it.
16939                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16940                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16941                        app.serviceHighRam = true;
16942                        app.serviceb = true;
16943                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16944                    } else {
16945                        mNewNumAServiceProcs++;
16946                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16947                    }
16948                } else {
16949                    app.serviceHighRam = false;
16950                }
16951            }
16952            if (app.serviceb) {
16953                adj = ProcessList.SERVICE_B_ADJ;
16954            }
16955        }
16956
16957        app.curRawAdj = adj;
16958
16959        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16960        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16961        if (adj > app.maxAdj) {
16962            adj = app.maxAdj;
16963            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16964                schedGroup = Process.THREAD_GROUP_DEFAULT;
16965            }
16966        }
16967
16968        // Do final modification to adj.  Everything we do between here and applying
16969        // the final setAdj must be done in this function, because we will also use
16970        // it when computing the final cached adj later.  Note that we don't need to
16971        // worry about this for max adj above, since max adj will always be used to
16972        // keep it out of the cached vaues.
16973        app.curAdj = app.modifyRawOomAdj(adj);
16974        app.curSchedGroup = schedGroup;
16975        app.curProcState = procState;
16976        app.foregroundActivities = foregroundActivities;
16977
16978        return app.curRawAdj;
16979    }
16980
16981    /**
16982     * Schedule PSS collection of a process.
16983     */
16984    void requestPssLocked(ProcessRecord proc, int procState) {
16985        if (mPendingPssProcesses.contains(proc)) {
16986            return;
16987        }
16988        if (mPendingPssProcesses.size() == 0) {
16989            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16990        }
16991        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16992        proc.pssProcState = procState;
16993        mPendingPssProcesses.add(proc);
16994    }
16995
16996    /**
16997     * Schedule PSS collection of all processes.
16998     */
16999    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17000        if (!always) {
17001            if (now < (mLastFullPssTime +
17002                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17003                return;
17004            }
17005        }
17006        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
17007        mLastFullPssTime = now;
17008        mFullPssPending = true;
17009        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17010        mPendingPssProcesses.clear();
17011        for (int i=mLruProcesses.size()-1; i>=0; i--) {
17012            ProcessRecord app = mLruProcesses.get(i);
17013            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17014                app.pssProcState = app.setProcState;
17015                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17016                        isSleeping(), now);
17017                mPendingPssProcesses.add(app);
17018            }
17019        }
17020        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17021    }
17022
17023    /**
17024     * Ask a given process to GC right now.
17025     */
17026    final void performAppGcLocked(ProcessRecord app) {
17027        try {
17028            app.lastRequestedGc = SystemClock.uptimeMillis();
17029            if (app.thread != null) {
17030                if (app.reportLowMemory) {
17031                    app.reportLowMemory = false;
17032                    app.thread.scheduleLowMemory();
17033                } else {
17034                    app.thread.processInBackground();
17035                }
17036            }
17037        } catch (Exception e) {
17038            // whatever.
17039        }
17040    }
17041
17042    /**
17043     * Returns true if things are idle enough to perform GCs.
17044     */
17045    private final boolean canGcNowLocked() {
17046        boolean processingBroadcasts = false;
17047        for (BroadcastQueue q : mBroadcastQueues) {
17048            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17049                processingBroadcasts = true;
17050            }
17051        }
17052        return !processingBroadcasts
17053                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17054    }
17055
17056    /**
17057     * Perform GCs on all processes that are waiting for it, but only
17058     * if things are idle.
17059     */
17060    final void performAppGcsLocked() {
17061        final int N = mProcessesToGc.size();
17062        if (N <= 0) {
17063            return;
17064        }
17065        if (canGcNowLocked()) {
17066            while (mProcessesToGc.size() > 0) {
17067                ProcessRecord proc = mProcessesToGc.remove(0);
17068                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17069                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17070                            <= SystemClock.uptimeMillis()) {
17071                        // To avoid spamming the system, we will GC processes one
17072                        // at a time, waiting a few seconds between each.
17073                        performAppGcLocked(proc);
17074                        scheduleAppGcsLocked();
17075                        return;
17076                    } else {
17077                        // It hasn't been long enough since we last GCed this
17078                        // process...  put it in the list to wait for its time.
17079                        addProcessToGcListLocked(proc);
17080                        break;
17081                    }
17082                }
17083            }
17084
17085            scheduleAppGcsLocked();
17086        }
17087    }
17088
17089    /**
17090     * If all looks good, perform GCs on all processes waiting for them.
17091     */
17092    final void performAppGcsIfAppropriateLocked() {
17093        if (canGcNowLocked()) {
17094            performAppGcsLocked();
17095            return;
17096        }
17097        // Still not idle, wait some more.
17098        scheduleAppGcsLocked();
17099    }
17100
17101    /**
17102     * Schedule the execution of all pending app GCs.
17103     */
17104    final void scheduleAppGcsLocked() {
17105        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17106
17107        if (mProcessesToGc.size() > 0) {
17108            // Schedule a GC for the time to the next process.
17109            ProcessRecord proc = mProcessesToGc.get(0);
17110            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17111
17112            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17113            long now = SystemClock.uptimeMillis();
17114            if (when < (now+GC_TIMEOUT)) {
17115                when = now + GC_TIMEOUT;
17116            }
17117            mHandler.sendMessageAtTime(msg, when);
17118        }
17119    }
17120
17121    /**
17122     * Add a process to the array of processes waiting to be GCed.  Keeps the
17123     * list in sorted order by the last GC time.  The process can't already be
17124     * on the list.
17125     */
17126    final void addProcessToGcListLocked(ProcessRecord proc) {
17127        boolean added = false;
17128        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17129            if (mProcessesToGc.get(i).lastRequestedGc <
17130                    proc.lastRequestedGc) {
17131                added = true;
17132                mProcessesToGc.add(i+1, proc);
17133                break;
17134            }
17135        }
17136        if (!added) {
17137            mProcessesToGc.add(0, proc);
17138        }
17139    }
17140
17141    /**
17142     * Set up to ask a process to GC itself.  This will either do it
17143     * immediately, or put it on the list of processes to gc the next
17144     * time things are idle.
17145     */
17146    final void scheduleAppGcLocked(ProcessRecord app) {
17147        long now = SystemClock.uptimeMillis();
17148        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17149            return;
17150        }
17151        if (!mProcessesToGc.contains(app)) {
17152            addProcessToGcListLocked(app);
17153            scheduleAppGcsLocked();
17154        }
17155    }
17156
17157    final void checkExcessivePowerUsageLocked(boolean doKills) {
17158        updateCpuStatsNow();
17159
17160        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17161        boolean doWakeKills = doKills;
17162        boolean doCpuKills = doKills;
17163        if (mLastPowerCheckRealtime == 0) {
17164            doWakeKills = false;
17165        }
17166        if (mLastPowerCheckUptime == 0) {
17167            doCpuKills = false;
17168        }
17169        if (stats.isScreenOn()) {
17170            doWakeKills = false;
17171        }
17172        final long curRealtime = SystemClock.elapsedRealtime();
17173        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17174        final long curUptime = SystemClock.uptimeMillis();
17175        final long uptimeSince = curUptime - mLastPowerCheckUptime;
17176        mLastPowerCheckRealtime = curRealtime;
17177        mLastPowerCheckUptime = curUptime;
17178        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17179            doWakeKills = false;
17180        }
17181        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17182            doCpuKills = false;
17183        }
17184        int i = mLruProcesses.size();
17185        while (i > 0) {
17186            i--;
17187            ProcessRecord app = mLruProcesses.get(i);
17188            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17189                long wtime;
17190                synchronized (stats) {
17191                    wtime = stats.getProcessWakeTime(app.info.uid,
17192                            app.pid, curRealtime);
17193                }
17194                long wtimeUsed = wtime - app.lastWakeTime;
17195                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17196                if (DEBUG_POWER) {
17197                    StringBuilder sb = new StringBuilder(128);
17198                    sb.append("Wake for ");
17199                    app.toShortString(sb);
17200                    sb.append(": over ");
17201                    TimeUtils.formatDuration(realtimeSince, sb);
17202                    sb.append(" used ");
17203                    TimeUtils.formatDuration(wtimeUsed, sb);
17204                    sb.append(" (");
17205                    sb.append((wtimeUsed*100)/realtimeSince);
17206                    sb.append("%)");
17207                    Slog.i(TAG, sb.toString());
17208                    sb.setLength(0);
17209                    sb.append("CPU for ");
17210                    app.toShortString(sb);
17211                    sb.append(": over ");
17212                    TimeUtils.formatDuration(uptimeSince, sb);
17213                    sb.append(" used ");
17214                    TimeUtils.formatDuration(cputimeUsed, sb);
17215                    sb.append(" (");
17216                    sb.append((cputimeUsed*100)/uptimeSince);
17217                    sb.append("%)");
17218                    Slog.i(TAG, sb.toString());
17219                }
17220                // If a process has held a wake lock for more
17221                // than 50% of the time during this period,
17222                // that sounds bad.  Kill!
17223                if (doWakeKills && realtimeSince > 0
17224                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
17225                    synchronized (stats) {
17226                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17227                                realtimeSince, wtimeUsed);
17228                    }
17229                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17230                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17231                } else if (doCpuKills && uptimeSince > 0
17232                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
17233                    synchronized (stats) {
17234                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17235                                uptimeSince, cputimeUsed);
17236                    }
17237                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17238                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17239                } else {
17240                    app.lastWakeTime = wtime;
17241                    app.lastCpuTime = app.curCpuTime;
17242                }
17243            }
17244        }
17245    }
17246
17247    private final boolean applyOomAdjLocked(ProcessRecord app,
17248            ProcessRecord TOP_APP, boolean doingAll, long now) {
17249        boolean success = true;
17250
17251        if (app.curRawAdj != app.setRawAdj) {
17252            app.setRawAdj = app.curRawAdj;
17253        }
17254
17255        int changes = 0;
17256
17257        if (app.curAdj != app.setAdj) {
17258            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17259            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17260                TAG, "Set " + app.pid + " " + app.processName +
17261                " adj " + app.curAdj + ": " + app.adjType);
17262            app.setAdj = app.curAdj;
17263        }
17264
17265        if (app.setSchedGroup != app.curSchedGroup) {
17266            app.setSchedGroup = app.curSchedGroup;
17267            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17268                    "Setting process group of " + app.processName
17269                    + " to " + app.curSchedGroup);
17270            if (app.waitingToKill != null &&
17271                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17272                app.kill(app.waitingToKill, true);
17273                success = false;
17274            } else {
17275                if (true) {
17276                    long oldId = Binder.clearCallingIdentity();
17277                    try {
17278                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17279                    } catch (Exception e) {
17280                        Slog.w(TAG, "Failed setting process group of " + app.pid
17281                                + " to " + app.curSchedGroup);
17282                        e.printStackTrace();
17283                    } finally {
17284                        Binder.restoreCallingIdentity(oldId);
17285                    }
17286                } else {
17287                    if (app.thread != null) {
17288                        try {
17289                            app.thread.setSchedulingGroup(app.curSchedGroup);
17290                        } catch (RemoteException e) {
17291                        }
17292                    }
17293                }
17294                Process.setSwappiness(app.pid,
17295                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17296            }
17297        }
17298        if (app.repForegroundActivities != app.foregroundActivities) {
17299            app.repForegroundActivities = app.foregroundActivities;
17300            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17301        }
17302        if (app.repProcState != app.curProcState) {
17303            app.repProcState = app.curProcState;
17304            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17305            if (app.thread != null) {
17306                try {
17307                    if (false) {
17308                        //RuntimeException h = new RuntimeException("here");
17309                        Slog.i(TAG, "Sending new process state " + app.repProcState
17310                                + " to " + app /*, h*/);
17311                    }
17312                    app.thread.setProcessState(app.repProcState);
17313                } catch (RemoteException e) {
17314                }
17315            }
17316        }
17317        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17318                app.setProcState)) {
17319            app.lastStateTime = now;
17320            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17321                    isSleeping(), now);
17322            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17323                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17324                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17325                    + (app.nextPssTime-now) + ": " + app);
17326        } else {
17327            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17328                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17329                requestPssLocked(app, app.setProcState);
17330                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17331                        isSleeping(), now);
17332            } else if (false && DEBUG_PSS) {
17333                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17334            }
17335        }
17336        if (app.setProcState != app.curProcState) {
17337            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17338                    "Proc state change of " + app.processName
17339                    + " to " + app.curProcState);
17340            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17341            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17342            if (setImportant && !curImportant) {
17343                // This app is no longer something we consider important enough to allow to
17344                // use arbitrary amounts of battery power.  Note
17345                // its current wake lock time to later know to kill it if
17346                // it is not behaving well.
17347                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17348                synchronized (stats) {
17349                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17350                            app.pid, SystemClock.elapsedRealtime());
17351                }
17352                app.lastCpuTime = app.curCpuTime;
17353
17354            }
17355            app.setProcState = app.curProcState;
17356            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17357                app.notCachedSinceIdle = false;
17358            }
17359            if (!doingAll) {
17360                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17361            } else {
17362                app.procStateChanged = true;
17363            }
17364        }
17365
17366        if (changes != 0) {
17367            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17368            int i = mPendingProcessChanges.size()-1;
17369            ProcessChangeItem item = null;
17370            while (i >= 0) {
17371                item = mPendingProcessChanges.get(i);
17372                if (item.pid == app.pid) {
17373                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17374                    break;
17375                }
17376                i--;
17377            }
17378            if (i < 0) {
17379                // No existing item in pending changes; need a new one.
17380                final int NA = mAvailProcessChanges.size();
17381                if (NA > 0) {
17382                    item = mAvailProcessChanges.remove(NA-1);
17383                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17384                } else {
17385                    item = new ProcessChangeItem();
17386                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17387                }
17388                item.changes = 0;
17389                item.pid = app.pid;
17390                item.uid = app.info.uid;
17391                if (mPendingProcessChanges.size() == 0) {
17392                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17393                            "*** Enqueueing dispatch processes changed!");
17394                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17395                }
17396                mPendingProcessChanges.add(item);
17397            }
17398            item.changes |= changes;
17399            item.processState = app.repProcState;
17400            item.foregroundActivities = app.repForegroundActivities;
17401            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17402                    + Integer.toHexString(System.identityHashCode(item))
17403                    + " " + app.toShortString() + ": changes=" + item.changes
17404                    + " procState=" + item.processState
17405                    + " foreground=" + item.foregroundActivities
17406                    + " type=" + app.adjType + " source=" + app.adjSource
17407                    + " target=" + app.adjTarget);
17408        }
17409
17410        return success;
17411    }
17412
17413    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17414        if (proc.thread != null) {
17415            if (proc.baseProcessTracker != null) {
17416                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17417            }
17418            if (proc.repProcState >= 0) {
17419                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17420                        proc.repProcState);
17421            }
17422        }
17423    }
17424
17425    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17426            ProcessRecord TOP_APP, boolean doingAll, long now) {
17427        if (app.thread == null) {
17428            return false;
17429        }
17430
17431        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17432
17433        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17434    }
17435
17436    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17437            boolean oomAdj) {
17438        if (isForeground != proc.foregroundServices) {
17439            proc.foregroundServices = isForeground;
17440            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17441                    proc.info.uid);
17442            if (isForeground) {
17443                if (curProcs == null) {
17444                    curProcs = new ArrayList<ProcessRecord>();
17445                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17446                }
17447                if (!curProcs.contains(proc)) {
17448                    curProcs.add(proc);
17449                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17450                            proc.info.packageName, proc.info.uid);
17451                }
17452            } else {
17453                if (curProcs != null) {
17454                    if (curProcs.remove(proc)) {
17455                        mBatteryStatsService.noteEvent(
17456                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17457                                proc.info.packageName, proc.info.uid);
17458                        if (curProcs.size() <= 0) {
17459                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17460                        }
17461                    }
17462                }
17463            }
17464            if (oomAdj) {
17465                updateOomAdjLocked();
17466            }
17467        }
17468    }
17469
17470    private final ActivityRecord resumedAppLocked() {
17471        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17472        String pkg;
17473        int uid;
17474        if (act != null) {
17475            pkg = act.packageName;
17476            uid = act.info.applicationInfo.uid;
17477        } else {
17478            pkg = null;
17479            uid = -1;
17480        }
17481        // Has the UID or resumed package name changed?
17482        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17483                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17484            if (mCurResumedPackage != null) {
17485                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17486                        mCurResumedPackage, mCurResumedUid);
17487            }
17488            mCurResumedPackage = pkg;
17489            mCurResumedUid = uid;
17490            if (mCurResumedPackage != null) {
17491                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17492                        mCurResumedPackage, mCurResumedUid);
17493            }
17494        }
17495        return act;
17496    }
17497
17498    final boolean updateOomAdjLocked(ProcessRecord app) {
17499        final ActivityRecord TOP_ACT = resumedAppLocked();
17500        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17501        final boolean wasCached = app.cached;
17502
17503        mAdjSeq++;
17504
17505        // This is the desired cached adjusment we want to tell it to use.
17506        // If our app is currently cached, we know it, and that is it.  Otherwise,
17507        // we don't know it yet, and it needs to now be cached we will then
17508        // need to do a complete oom adj.
17509        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17510                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17511        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17512                SystemClock.uptimeMillis());
17513        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17514            // Changed to/from cached state, so apps after it in the LRU
17515            // list may also be changed.
17516            updateOomAdjLocked();
17517        }
17518        return success;
17519    }
17520
17521    final void updateOomAdjLocked() {
17522        final ActivityRecord TOP_ACT = resumedAppLocked();
17523        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17524        final long now = SystemClock.uptimeMillis();
17525        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17526        final int N = mLruProcesses.size();
17527
17528        if (false) {
17529            RuntimeException e = new RuntimeException();
17530            e.fillInStackTrace();
17531            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17532        }
17533
17534        mAdjSeq++;
17535        mNewNumServiceProcs = 0;
17536        mNewNumAServiceProcs = 0;
17537
17538        final int emptyProcessLimit;
17539        final int cachedProcessLimit;
17540        if (mProcessLimit <= 0) {
17541            emptyProcessLimit = cachedProcessLimit = 0;
17542        } else if (mProcessLimit == 1) {
17543            emptyProcessLimit = 1;
17544            cachedProcessLimit = 0;
17545        } else {
17546            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17547            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17548        }
17549
17550        // Let's determine how many processes we have running vs.
17551        // how many slots we have for background processes; we may want
17552        // to put multiple processes in a slot of there are enough of
17553        // them.
17554        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17555                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17556        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17557        if (numEmptyProcs > cachedProcessLimit) {
17558            // If there are more empty processes than our limit on cached
17559            // processes, then use the cached process limit for the factor.
17560            // This ensures that the really old empty processes get pushed
17561            // down to the bottom, so if we are running low on memory we will
17562            // have a better chance at keeping around more cached processes
17563            // instead of a gazillion empty processes.
17564            numEmptyProcs = cachedProcessLimit;
17565        }
17566        int emptyFactor = numEmptyProcs/numSlots;
17567        if (emptyFactor < 1) emptyFactor = 1;
17568        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17569        if (cachedFactor < 1) cachedFactor = 1;
17570        int stepCached = 0;
17571        int stepEmpty = 0;
17572        int numCached = 0;
17573        int numEmpty = 0;
17574        int numTrimming = 0;
17575
17576        mNumNonCachedProcs = 0;
17577        mNumCachedHiddenProcs = 0;
17578
17579        // First update the OOM adjustment for each of the
17580        // application processes based on their current state.
17581        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17582        int nextCachedAdj = curCachedAdj+1;
17583        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17584        int nextEmptyAdj = curEmptyAdj+2;
17585        for (int i=N-1; i>=0; i--) {
17586            ProcessRecord app = mLruProcesses.get(i);
17587            if (!app.killedByAm && app.thread != null) {
17588                app.procStateChanged = false;
17589                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17590
17591                // If we haven't yet assigned the final cached adj
17592                // to the process, do that now.
17593                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17594                    switch (app.curProcState) {
17595                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17596                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17597                            // This process is a cached process holding activities...
17598                            // assign it the next cached value for that type, and then
17599                            // step that cached level.
17600                            app.curRawAdj = curCachedAdj;
17601                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17602                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17603                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17604                                    + ")");
17605                            if (curCachedAdj != nextCachedAdj) {
17606                                stepCached++;
17607                                if (stepCached >= cachedFactor) {
17608                                    stepCached = 0;
17609                                    curCachedAdj = nextCachedAdj;
17610                                    nextCachedAdj += 2;
17611                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17612                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17613                                    }
17614                                }
17615                            }
17616                            break;
17617                        default:
17618                            // For everything else, assign next empty cached process
17619                            // level and bump that up.  Note that this means that
17620                            // long-running services that have dropped down to the
17621                            // cached level will be treated as empty (since their process
17622                            // state is still as a service), which is what we want.
17623                            app.curRawAdj = curEmptyAdj;
17624                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17625                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17626                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17627                                    + ")");
17628                            if (curEmptyAdj != nextEmptyAdj) {
17629                                stepEmpty++;
17630                                if (stepEmpty >= emptyFactor) {
17631                                    stepEmpty = 0;
17632                                    curEmptyAdj = nextEmptyAdj;
17633                                    nextEmptyAdj += 2;
17634                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17635                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17636                                    }
17637                                }
17638                            }
17639                            break;
17640                    }
17641                }
17642
17643                applyOomAdjLocked(app, TOP_APP, true, now);
17644
17645                // Count the number of process types.
17646                switch (app.curProcState) {
17647                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17648                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17649                        mNumCachedHiddenProcs++;
17650                        numCached++;
17651                        if (numCached > cachedProcessLimit) {
17652                            app.kill("cached #" + numCached, true);
17653                        }
17654                        break;
17655                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17656                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17657                                && app.lastActivityTime < oldTime) {
17658                            app.kill("empty for "
17659                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17660                                    / 1000) + "s", true);
17661                        } else {
17662                            numEmpty++;
17663                            if (numEmpty > emptyProcessLimit) {
17664                                app.kill("empty #" + numEmpty, true);
17665                            }
17666                        }
17667                        break;
17668                    default:
17669                        mNumNonCachedProcs++;
17670                        break;
17671                }
17672
17673                if (app.isolated && app.services.size() <= 0) {
17674                    // If this is an isolated process, and there are no
17675                    // services running in it, then the process is no longer
17676                    // needed.  We agressively kill these because we can by
17677                    // definition not re-use the same process again, and it is
17678                    // good to avoid having whatever code was running in them
17679                    // left sitting around after no longer needed.
17680                    app.kill("isolated not needed", true);
17681                }
17682
17683                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17684                        && !app.killedByAm) {
17685                    numTrimming++;
17686                }
17687            }
17688        }
17689
17690        mNumServiceProcs = mNewNumServiceProcs;
17691
17692        // Now determine the memory trimming level of background processes.
17693        // Unfortunately we need to start at the back of the list to do this
17694        // properly.  We only do this if the number of background apps we
17695        // are managing to keep around is less than half the maximum we desire;
17696        // if we are keeping a good number around, we'll let them use whatever
17697        // memory they want.
17698        final int numCachedAndEmpty = numCached + numEmpty;
17699        int memFactor;
17700        if (numCached <= ProcessList.TRIM_CACHED_APPS
17701                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17702            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17703                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17704            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17705                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17706            } else {
17707                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17708            }
17709        } else {
17710            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17711        }
17712        // We always allow the memory level to go up (better).  We only allow it to go
17713        // down if we are in a state where that is allowed, *and* the total number of processes
17714        // has gone down since last time.
17715        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17716                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17717                + " last=" + mLastNumProcesses);
17718        if (memFactor > mLastMemoryLevel) {
17719            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17720                memFactor = mLastMemoryLevel;
17721                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17722            }
17723        }
17724        mLastMemoryLevel = memFactor;
17725        mLastNumProcesses = mLruProcesses.size();
17726        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17727        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17728        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17729            if (mLowRamStartTime == 0) {
17730                mLowRamStartTime = now;
17731            }
17732            int step = 0;
17733            int fgTrimLevel;
17734            switch (memFactor) {
17735                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17736                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17737                    break;
17738                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17739                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17740                    break;
17741                default:
17742                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17743                    break;
17744            }
17745            int factor = numTrimming/3;
17746            int minFactor = 2;
17747            if (mHomeProcess != null) minFactor++;
17748            if (mPreviousProcess != null) minFactor++;
17749            if (factor < minFactor) factor = minFactor;
17750            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17751            for (int i=N-1; i>=0; i--) {
17752                ProcessRecord app = mLruProcesses.get(i);
17753                if (allChanged || app.procStateChanged) {
17754                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17755                    app.procStateChanged = false;
17756                }
17757                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17758                        && !app.killedByAm) {
17759                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17760                        try {
17761                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17762                                    "Trimming memory of " + app.processName
17763                                    + " to " + curLevel);
17764                            app.thread.scheduleTrimMemory(curLevel);
17765                        } catch (RemoteException e) {
17766                        }
17767                        if (false) {
17768                            // For now we won't do this; our memory trimming seems
17769                            // to be good enough at this point that destroying
17770                            // activities causes more harm than good.
17771                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17772                                    && app != mHomeProcess && app != mPreviousProcess) {
17773                                // Need to do this on its own message because the stack may not
17774                                // be in a consistent state at this point.
17775                                // For these apps we will also finish their activities
17776                                // to help them free memory.
17777                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17778                            }
17779                        }
17780                    }
17781                    app.trimMemoryLevel = curLevel;
17782                    step++;
17783                    if (step >= factor) {
17784                        step = 0;
17785                        switch (curLevel) {
17786                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17787                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17788                                break;
17789                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17790                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17791                                break;
17792                        }
17793                    }
17794                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17795                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17796                            && app.thread != null) {
17797                        try {
17798                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17799                                    "Trimming memory of heavy-weight " + app.processName
17800                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17801                            app.thread.scheduleTrimMemory(
17802                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17803                        } catch (RemoteException e) {
17804                        }
17805                    }
17806                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17807                } else {
17808                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17809                            || app.systemNoUi) && app.pendingUiClean) {
17810                        // If this application is now in the background and it
17811                        // had done UI, then give it the special trim level to
17812                        // have it free UI resources.
17813                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17814                        if (app.trimMemoryLevel < level && app.thread != null) {
17815                            try {
17816                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17817                                        "Trimming memory of bg-ui " + app.processName
17818                                        + " to " + level);
17819                                app.thread.scheduleTrimMemory(level);
17820                            } catch (RemoteException e) {
17821                            }
17822                        }
17823                        app.pendingUiClean = false;
17824                    }
17825                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17826                        try {
17827                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17828                                    "Trimming memory of fg " + app.processName
17829                                    + " to " + fgTrimLevel);
17830                            app.thread.scheduleTrimMemory(fgTrimLevel);
17831                        } catch (RemoteException e) {
17832                        }
17833                    }
17834                    app.trimMemoryLevel = fgTrimLevel;
17835                }
17836            }
17837        } else {
17838            if (mLowRamStartTime != 0) {
17839                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17840                mLowRamStartTime = 0;
17841            }
17842            for (int i=N-1; i>=0; i--) {
17843                ProcessRecord app = mLruProcesses.get(i);
17844                if (allChanged || app.procStateChanged) {
17845                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17846                    app.procStateChanged = false;
17847                }
17848                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17849                        || app.systemNoUi) && app.pendingUiClean) {
17850                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17851                            && app.thread != null) {
17852                        try {
17853                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17854                                    "Trimming memory of ui hidden " + app.processName
17855                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17856                            app.thread.scheduleTrimMemory(
17857                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17858                        } catch (RemoteException e) {
17859                        }
17860                    }
17861                    app.pendingUiClean = false;
17862                }
17863                app.trimMemoryLevel = 0;
17864            }
17865        }
17866
17867        if (mAlwaysFinishActivities) {
17868            // Need to do this on its own message because the stack may not
17869            // be in a consistent state at this point.
17870            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17871        }
17872
17873        if (allChanged) {
17874            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17875        }
17876
17877        if (mProcessStats.shouldWriteNowLocked(now)) {
17878            mHandler.post(new Runnable() {
17879                @Override public void run() {
17880                    synchronized (ActivityManagerService.this) {
17881                        mProcessStats.writeStateAsyncLocked();
17882                    }
17883                }
17884            });
17885        }
17886
17887        if (DEBUG_OOM_ADJ) {
17888            if (false) {
17889                RuntimeException here = new RuntimeException("here");
17890                here.fillInStackTrace();
17891                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
17892            } else {
17893                Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17894            }
17895        }
17896    }
17897
17898    final void trimApplications() {
17899        synchronized (this) {
17900            int i;
17901
17902            // First remove any unused application processes whose package
17903            // has been removed.
17904            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17905                final ProcessRecord app = mRemovedProcesses.get(i);
17906                if (app.activities.size() == 0
17907                        && app.curReceiver == null && app.services.size() == 0) {
17908                    Slog.i(
17909                        TAG, "Exiting empty application process "
17910                        + app.processName + " ("
17911                        + (app.thread != null ? app.thread.asBinder() : null)
17912                        + ")\n");
17913                    if (app.pid > 0 && app.pid != MY_PID) {
17914                        app.kill("empty", false);
17915                    } else {
17916                        try {
17917                            app.thread.scheduleExit();
17918                        } catch (Exception e) {
17919                            // Ignore exceptions.
17920                        }
17921                    }
17922                    cleanUpApplicationRecordLocked(app, false, true, -1);
17923                    mRemovedProcesses.remove(i);
17924
17925                    if (app.persistent) {
17926                        addAppLocked(app.info, false, null /* ABI override */);
17927                    }
17928                }
17929            }
17930
17931            // Now update the oom adj for all processes.
17932            updateOomAdjLocked();
17933        }
17934    }
17935
17936    /** This method sends the specified signal to each of the persistent apps */
17937    public void signalPersistentProcesses(int sig) throws RemoteException {
17938        if (sig != Process.SIGNAL_USR1) {
17939            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17940        }
17941
17942        synchronized (this) {
17943            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17944                    != PackageManager.PERMISSION_GRANTED) {
17945                throw new SecurityException("Requires permission "
17946                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17947            }
17948
17949            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17950                ProcessRecord r = mLruProcesses.get(i);
17951                if (r.thread != null && r.persistent) {
17952                    Process.sendSignal(r.pid, sig);
17953                }
17954            }
17955        }
17956    }
17957
17958    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17959        if (proc == null || proc == mProfileProc) {
17960            proc = mProfileProc;
17961            profileType = mProfileType;
17962            clearProfilerLocked();
17963        }
17964        if (proc == null) {
17965            return;
17966        }
17967        try {
17968            proc.thread.profilerControl(false, null, profileType);
17969        } catch (RemoteException e) {
17970            throw new IllegalStateException("Process disappeared");
17971        }
17972    }
17973
17974    private void clearProfilerLocked() {
17975        if (mProfileFd != null) {
17976            try {
17977                mProfileFd.close();
17978            } catch (IOException e) {
17979            }
17980        }
17981        mProfileApp = null;
17982        mProfileProc = null;
17983        mProfileFile = null;
17984        mProfileType = 0;
17985        mAutoStopProfiler = false;
17986        mSamplingInterval = 0;
17987    }
17988
17989    public boolean profileControl(String process, int userId, boolean start,
17990            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17991
17992        try {
17993            synchronized (this) {
17994                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17995                // its own permission.
17996                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17997                        != PackageManager.PERMISSION_GRANTED) {
17998                    throw new SecurityException("Requires permission "
17999                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18000                }
18001
18002                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18003                    throw new IllegalArgumentException("null profile info or fd");
18004                }
18005
18006                ProcessRecord proc = null;
18007                if (process != null) {
18008                    proc = findProcessLocked(process, userId, "profileControl");
18009                }
18010
18011                if (start && (proc == null || proc.thread == null)) {
18012                    throw new IllegalArgumentException("Unknown process: " + process);
18013                }
18014
18015                if (start) {
18016                    stopProfilerLocked(null, 0);
18017                    setProfileApp(proc.info, proc.processName, profilerInfo);
18018                    mProfileProc = proc;
18019                    mProfileType = profileType;
18020                    ParcelFileDescriptor fd = profilerInfo.profileFd;
18021                    try {
18022                        fd = fd.dup();
18023                    } catch (IOException e) {
18024                        fd = null;
18025                    }
18026                    profilerInfo.profileFd = fd;
18027                    proc.thread.profilerControl(start, profilerInfo, profileType);
18028                    fd = null;
18029                    mProfileFd = null;
18030                } else {
18031                    stopProfilerLocked(proc, profileType);
18032                    if (profilerInfo != null && profilerInfo.profileFd != null) {
18033                        try {
18034                            profilerInfo.profileFd.close();
18035                        } catch (IOException e) {
18036                        }
18037                    }
18038                }
18039
18040                return true;
18041            }
18042        } catch (RemoteException e) {
18043            throw new IllegalStateException("Process disappeared");
18044        } finally {
18045            if (profilerInfo != null && profilerInfo.profileFd != null) {
18046                try {
18047                    profilerInfo.profileFd.close();
18048                } catch (IOException e) {
18049                }
18050            }
18051        }
18052    }
18053
18054    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18055        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18056                userId, true, ALLOW_FULL_ONLY, callName, null);
18057        ProcessRecord proc = null;
18058        try {
18059            int pid = Integer.parseInt(process);
18060            synchronized (mPidsSelfLocked) {
18061                proc = mPidsSelfLocked.get(pid);
18062            }
18063        } catch (NumberFormatException e) {
18064        }
18065
18066        if (proc == null) {
18067            ArrayMap<String, SparseArray<ProcessRecord>> all
18068                    = mProcessNames.getMap();
18069            SparseArray<ProcessRecord> procs = all.get(process);
18070            if (procs != null && procs.size() > 0) {
18071                proc = procs.valueAt(0);
18072                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18073                    for (int i=1; i<procs.size(); i++) {
18074                        ProcessRecord thisProc = procs.valueAt(i);
18075                        if (thisProc.userId == userId) {
18076                            proc = thisProc;
18077                            break;
18078                        }
18079                    }
18080                }
18081            }
18082        }
18083
18084        return proc;
18085    }
18086
18087    public boolean dumpHeap(String process, int userId, boolean managed,
18088            String path, ParcelFileDescriptor fd) throws RemoteException {
18089
18090        try {
18091            synchronized (this) {
18092                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18093                // its own permission (same as profileControl).
18094                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18095                        != PackageManager.PERMISSION_GRANTED) {
18096                    throw new SecurityException("Requires permission "
18097                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18098                }
18099
18100                if (fd == null) {
18101                    throw new IllegalArgumentException("null fd");
18102                }
18103
18104                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18105                if (proc == null || proc.thread == null) {
18106                    throw new IllegalArgumentException("Unknown process: " + process);
18107                }
18108
18109                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18110                if (!isDebuggable) {
18111                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18112                        throw new SecurityException("Process not debuggable: " + proc);
18113                    }
18114                }
18115
18116                proc.thread.dumpHeap(managed, path, fd);
18117                fd = null;
18118                return true;
18119            }
18120        } catch (RemoteException e) {
18121            throw new IllegalStateException("Process disappeared");
18122        } finally {
18123            if (fd != null) {
18124                try {
18125                    fd.close();
18126                } catch (IOException e) {
18127                }
18128            }
18129        }
18130    }
18131
18132    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18133    public void monitor() {
18134        synchronized (this) { }
18135    }
18136
18137    void onCoreSettingsChange(Bundle settings) {
18138        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18139            ProcessRecord processRecord = mLruProcesses.get(i);
18140            try {
18141                if (processRecord.thread != null) {
18142                    processRecord.thread.setCoreSettings(settings);
18143                }
18144            } catch (RemoteException re) {
18145                /* ignore */
18146            }
18147        }
18148    }
18149
18150    // Multi-user methods
18151
18152    /**
18153     * Start user, if its not already running, but don't bring it to foreground.
18154     */
18155    @Override
18156    public boolean startUserInBackground(final int userId) {
18157        return startUser(userId, /* foreground */ false);
18158    }
18159
18160    /**
18161     * Start user, if its not already running, and bring it to foreground.
18162     */
18163    boolean startUserInForeground(final int userId, Dialog dlg) {
18164        boolean result = startUser(userId, /* foreground */ true);
18165        dlg.dismiss();
18166        return result;
18167    }
18168
18169    /**
18170     * Refreshes the list of users related to the current user when either a
18171     * user switch happens or when a new related user is started in the
18172     * background.
18173     */
18174    private void updateCurrentProfileIdsLocked() {
18175        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18176                mCurrentUserId, false /* enabledOnly */);
18177        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18178        for (int i = 0; i < currentProfileIds.length; i++) {
18179            currentProfileIds[i] = profiles.get(i).id;
18180        }
18181        mCurrentProfileIds = currentProfileIds;
18182
18183        synchronized (mUserProfileGroupIdsSelfLocked) {
18184            mUserProfileGroupIdsSelfLocked.clear();
18185            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18186            for (int i = 0; i < users.size(); i++) {
18187                UserInfo user = users.get(i);
18188                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18189                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18190                }
18191            }
18192        }
18193    }
18194
18195    private Set getProfileIdsLocked(int userId) {
18196        Set userIds = new HashSet<Integer>();
18197        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18198                userId, false /* enabledOnly */);
18199        for (UserInfo user : profiles) {
18200            userIds.add(Integer.valueOf(user.id));
18201        }
18202        return userIds;
18203    }
18204
18205    @Override
18206    public boolean switchUser(final int userId) {
18207        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18208        String userName;
18209        synchronized (this) {
18210            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18211            if (userInfo == null) {
18212                Slog.w(TAG, "No user info for user #" + userId);
18213                return false;
18214            }
18215            if (userInfo.isManagedProfile()) {
18216                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18217                return false;
18218            }
18219            userName = userInfo.name;
18220            mTargetUserId = userId;
18221        }
18222        mHandler.removeMessages(START_USER_SWITCH_MSG);
18223        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18224        return true;
18225    }
18226
18227    private void showUserSwitchDialog(int userId, String userName) {
18228        // The dialog will show and then initiate the user switch by calling startUserInForeground
18229        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18230                true /* above system */);
18231        d.show();
18232    }
18233
18234    private boolean startUser(final int userId, final boolean foreground) {
18235        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18236                != PackageManager.PERMISSION_GRANTED) {
18237            String msg = "Permission Denial: switchUser() from pid="
18238                    + Binder.getCallingPid()
18239                    + ", uid=" + Binder.getCallingUid()
18240                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18241            Slog.w(TAG, msg);
18242            throw new SecurityException(msg);
18243        }
18244
18245        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18246
18247        final long ident = Binder.clearCallingIdentity();
18248        try {
18249            synchronized (this) {
18250                final int oldUserId = mCurrentUserId;
18251                if (oldUserId == userId) {
18252                    return true;
18253                }
18254
18255                mStackSupervisor.setLockTaskModeLocked(null, false);
18256
18257                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18258                if (userInfo == null) {
18259                    Slog.w(TAG, "No user info for user #" + userId);
18260                    return false;
18261                }
18262                if (foreground && userInfo.isManagedProfile()) {
18263                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18264                    return false;
18265                }
18266
18267                if (foreground) {
18268                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18269                            R.anim.screen_user_enter);
18270                }
18271
18272                boolean needStart = false;
18273
18274                // If the user we are switching to is not currently started, then
18275                // we need to start it now.
18276                if (mStartedUsers.get(userId) == null) {
18277                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18278                    updateStartedUserArrayLocked();
18279                    needStart = true;
18280                }
18281
18282                final Integer userIdInt = Integer.valueOf(userId);
18283                mUserLru.remove(userIdInt);
18284                mUserLru.add(userIdInt);
18285
18286                if (foreground) {
18287                    mCurrentUserId = userId;
18288                    mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18289                    updateCurrentProfileIdsLocked();
18290                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18291                    // Once the internal notion of the active user has switched, we lock the device
18292                    // with the option to show the user switcher on the keyguard.
18293                    mWindowManager.lockNow(null);
18294                } else {
18295                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18296                    updateCurrentProfileIdsLocked();
18297                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18298                    mUserLru.remove(currentUserIdInt);
18299                    mUserLru.add(currentUserIdInt);
18300                }
18301
18302                final UserStartedState uss = mStartedUsers.get(userId);
18303
18304                // Make sure user is in the started state.  If it is currently
18305                // stopping, we need to knock that off.
18306                if (uss.mState == UserStartedState.STATE_STOPPING) {
18307                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18308                    // so we can just fairly silently bring the user back from
18309                    // the almost-dead.
18310                    uss.mState = UserStartedState.STATE_RUNNING;
18311                    updateStartedUserArrayLocked();
18312                    needStart = true;
18313                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18314                    // This means ACTION_SHUTDOWN has been sent, so we will
18315                    // need to treat this as a new boot of the user.
18316                    uss.mState = UserStartedState.STATE_BOOTING;
18317                    updateStartedUserArrayLocked();
18318                    needStart = true;
18319                }
18320
18321                if (uss.mState == UserStartedState.STATE_BOOTING) {
18322                    // Booting up a new user, need to tell system services about it.
18323                    // Note that this is on the same handler as scheduling of broadcasts,
18324                    // which is important because it needs to go first.
18325                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18326                }
18327
18328                if (foreground) {
18329                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18330                            oldUserId));
18331                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18332                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18333                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18334                            oldUserId, userId, uss));
18335                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18336                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18337                }
18338
18339                if (needStart) {
18340                    // Send USER_STARTED broadcast
18341                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18342                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18343                            | Intent.FLAG_RECEIVER_FOREGROUND);
18344                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18345                    broadcastIntentLocked(null, null, intent,
18346                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18347                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18348                }
18349
18350                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18351                    if (userId != UserHandle.USER_OWNER) {
18352                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18353                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18354                        broadcastIntentLocked(null, null, intent, null,
18355                                new IIntentReceiver.Stub() {
18356                                    public void performReceive(Intent intent, int resultCode,
18357                                            String data, Bundle extras, boolean ordered,
18358                                            boolean sticky, int sendingUser) {
18359                                        onUserInitialized(uss, foreground, oldUserId, userId);
18360                                    }
18361                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18362                                true, false, MY_PID, Process.SYSTEM_UID,
18363                                userId);
18364                        uss.initializing = true;
18365                    } else {
18366                        getUserManagerLocked().makeInitialized(userInfo.id);
18367                    }
18368                }
18369
18370                if (foreground) {
18371                    if (!uss.initializing) {
18372                        moveUserToForeground(uss, oldUserId, userId);
18373                    }
18374                } else {
18375                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18376                }
18377
18378                if (needStart) {
18379                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18380                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18381                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18382                    broadcastIntentLocked(null, null, intent,
18383                            null, new IIntentReceiver.Stub() {
18384                                @Override
18385                                public void performReceive(Intent intent, int resultCode, String data,
18386                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18387                                        throws RemoteException {
18388                                }
18389                            }, 0, null, null,
18390                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18391                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18392                }
18393            }
18394        } finally {
18395            Binder.restoreCallingIdentity(ident);
18396        }
18397
18398        return true;
18399    }
18400
18401    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18402        long ident = Binder.clearCallingIdentity();
18403        try {
18404            Intent intent;
18405            if (oldUserId >= 0) {
18406                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18407                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18408                int count = profiles.size();
18409                for (int i = 0; i < count; i++) {
18410                    int profileUserId = profiles.get(i).id;
18411                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18412                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18413                            | Intent.FLAG_RECEIVER_FOREGROUND);
18414                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18415                    broadcastIntentLocked(null, null, intent,
18416                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18417                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18418                }
18419            }
18420            if (newUserId >= 0) {
18421                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18422                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18423                int count = profiles.size();
18424                for (int i = 0; i < count; i++) {
18425                    int profileUserId = profiles.get(i).id;
18426                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18427                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18428                            | Intent.FLAG_RECEIVER_FOREGROUND);
18429                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18430                    broadcastIntentLocked(null, null, intent,
18431                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18432                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18433                }
18434                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18435                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18436                        | Intent.FLAG_RECEIVER_FOREGROUND);
18437                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18438                broadcastIntentLocked(null, null, intent,
18439                        null, null, 0, null, null,
18440                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18441                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18442            }
18443        } finally {
18444            Binder.restoreCallingIdentity(ident);
18445        }
18446    }
18447
18448    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18449            final int newUserId) {
18450        final int N = mUserSwitchObservers.beginBroadcast();
18451        if (N > 0) {
18452            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18453                int mCount = 0;
18454                @Override
18455                public void sendResult(Bundle data) throws RemoteException {
18456                    synchronized (ActivityManagerService.this) {
18457                        if (mCurUserSwitchCallback == this) {
18458                            mCount++;
18459                            if (mCount == N) {
18460                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18461                            }
18462                        }
18463                    }
18464                }
18465            };
18466            synchronized (this) {
18467                uss.switching = true;
18468                mCurUserSwitchCallback = callback;
18469            }
18470            for (int i=0; i<N; i++) {
18471                try {
18472                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18473                            newUserId, callback);
18474                } catch (RemoteException e) {
18475                }
18476            }
18477        } else {
18478            synchronized (this) {
18479                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18480            }
18481        }
18482        mUserSwitchObservers.finishBroadcast();
18483    }
18484
18485    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18486        synchronized (this) {
18487            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18488            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18489        }
18490    }
18491
18492    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18493        mCurUserSwitchCallback = null;
18494        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18495        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18496                oldUserId, newUserId, uss));
18497    }
18498
18499    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18500        synchronized (this) {
18501            if (foreground) {
18502                moveUserToForeground(uss, oldUserId, newUserId);
18503            }
18504        }
18505
18506        completeSwitchAndInitalize(uss, newUserId, true, false);
18507    }
18508
18509    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18510        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18511        if (homeInFront) {
18512            startHomeActivityLocked(newUserId);
18513        } else {
18514            mStackSupervisor.resumeTopActivitiesLocked();
18515        }
18516        EventLogTags.writeAmSwitchUser(newUserId);
18517        getUserManagerLocked().userForeground(newUserId);
18518        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18519    }
18520
18521    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18522        completeSwitchAndInitalize(uss, newUserId, false, true);
18523    }
18524
18525    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18526            boolean clearInitializing, boolean clearSwitching) {
18527        boolean unfrozen = false;
18528        synchronized (this) {
18529            if (clearInitializing) {
18530                uss.initializing = false;
18531                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18532            }
18533            if (clearSwitching) {
18534                uss.switching = false;
18535            }
18536            if (!uss.switching && !uss.initializing) {
18537                mWindowManager.stopFreezingScreen();
18538                unfrozen = true;
18539            }
18540        }
18541        if (unfrozen) {
18542            final int N = mUserSwitchObservers.beginBroadcast();
18543            for (int i=0; i<N; i++) {
18544                try {
18545                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18546                } catch (RemoteException e) {
18547                }
18548            }
18549            mUserSwitchObservers.finishBroadcast();
18550        }
18551    }
18552
18553    void scheduleStartProfilesLocked() {
18554        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18555            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18556                    DateUtils.SECOND_IN_MILLIS);
18557        }
18558    }
18559
18560    void startProfilesLocked() {
18561        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18562        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18563                mCurrentUserId, false /* enabledOnly */);
18564        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18565        for (UserInfo user : profiles) {
18566            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18567                    && user.id != mCurrentUserId) {
18568                toStart.add(user);
18569            }
18570        }
18571        final int n = toStart.size();
18572        int i = 0;
18573        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18574            startUserInBackground(toStart.get(i).id);
18575        }
18576        if (i < n) {
18577            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18578        }
18579    }
18580
18581    void finishUserBoot(UserStartedState uss) {
18582        synchronized (this) {
18583            if (uss.mState == UserStartedState.STATE_BOOTING
18584                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18585                uss.mState = UserStartedState.STATE_RUNNING;
18586                final int userId = uss.mHandle.getIdentifier();
18587                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18588                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18589                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18590                broadcastIntentLocked(null, null, intent,
18591                        null, null, 0, null, null,
18592                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18593                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18594            }
18595        }
18596    }
18597
18598    void finishUserSwitch(UserStartedState uss) {
18599        synchronized (this) {
18600            finishUserBoot(uss);
18601
18602            startProfilesLocked();
18603
18604            int num = mUserLru.size();
18605            int i = 0;
18606            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18607                Integer oldUserId = mUserLru.get(i);
18608                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18609                if (oldUss == null) {
18610                    // Shouldn't happen, but be sane if it does.
18611                    mUserLru.remove(i);
18612                    num--;
18613                    continue;
18614                }
18615                if (oldUss.mState == UserStartedState.STATE_STOPPING
18616                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18617                    // This user is already stopping, doesn't count.
18618                    num--;
18619                    i++;
18620                    continue;
18621                }
18622                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18623                    // Owner and current can't be stopped, but count as running.
18624                    i++;
18625                    continue;
18626                }
18627                // This is a user to be stopped.
18628                stopUserLocked(oldUserId, null);
18629                num--;
18630                i++;
18631            }
18632        }
18633    }
18634
18635    @Override
18636    public int stopUser(final int userId, final IStopUserCallback callback) {
18637        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18638                != PackageManager.PERMISSION_GRANTED) {
18639            String msg = "Permission Denial: switchUser() from pid="
18640                    + Binder.getCallingPid()
18641                    + ", uid=" + Binder.getCallingUid()
18642                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18643            Slog.w(TAG, msg);
18644            throw new SecurityException(msg);
18645        }
18646        if (userId <= 0) {
18647            throw new IllegalArgumentException("Can't stop primary user " + userId);
18648        }
18649        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18650        synchronized (this) {
18651            return stopUserLocked(userId, callback);
18652        }
18653    }
18654
18655    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18656        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18657        if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18658            return ActivityManager.USER_OP_IS_CURRENT;
18659        }
18660
18661        final UserStartedState uss = mStartedUsers.get(userId);
18662        if (uss == null) {
18663            // User is not started, nothing to do...  but we do need to
18664            // callback if requested.
18665            if (callback != null) {
18666                mHandler.post(new Runnable() {
18667                    @Override
18668                    public void run() {
18669                        try {
18670                            callback.userStopped(userId);
18671                        } catch (RemoteException e) {
18672                        }
18673                    }
18674                });
18675            }
18676            return ActivityManager.USER_OP_SUCCESS;
18677        }
18678
18679        if (callback != null) {
18680            uss.mStopCallbacks.add(callback);
18681        }
18682
18683        if (uss.mState != UserStartedState.STATE_STOPPING
18684                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18685            uss.mState = UserStartedState.STATE_STOPPING;
18686            updateStartedUserArrayLocked();
18687
18688            long ident = Binder.clearCallingIdentity();
18689            try {
18690                // We are going to broadcast ACTION_USER_STOPPING and then
18691                // once that is done send a final ACTION_SHUTDOWN and then
18692                // stop the user.
18693                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18694                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18695                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18696                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18697                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18698                // This is the result receiver for the final shutdown broadcast.
18699                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18700                    @Override
18701                    public void performReceive(Intent intent, int resultCode, String data,
18702                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18703                        finishUserStop(uss);
18704                    }
18705                };
18706                // This is the result receiver for the initial stopping broadcast.
18707                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18708                    @Override
18709                    public void performReceive(Intent intent, int resultCode, String data,
18710                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18711                        // On to the next.
18712                        synchronized (ActivityManagerService.this) {
18713                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18714                                // Whoops, we are being started back up.  Abort, abort!
18715                                return;
18716                            }
18717                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18718                        }
18719                        mBatteryStatsService.noteEvent(
18720                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18721                                Integer.toString(userId), userId);
18722                        mSystemServiceManager.stopUser(userId);
18723                        broadcastIntentLocked(null, null, shutdownIntent,
18724                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18725                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18726                    }
18727                };
18728                // Kick things off.
18729                broadcastIntentLocked(null, null, stoppingIntent,
18730                        null, stoppingReceiver, 0, null, null,
18731                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18732                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18733            } finally {
18734                Binder.restoreCallingIdentity(ident);
18735            }
18736        }
18737
18738        return ActivityManager.USER_OP_SUCCESS;
18739    }
18740
18741    void finishUserStop(UserStartedState uss) {
18742        final int userId = uss.mHandle.getIdentifier();
18743        boolean stopped;
18744        ArrayList<IStopUserCallback> callbacks;
18745        synchronized (this) {
18746            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18747            if (mStartedUsers.get(userId) != uss) {
18748                stopped = false;
18749            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18750                stopped = false;
18751            } else {
18752                stopped = true;
18753                // User can no longer run.
18754                mStartedUsers.remove(userId);
18755                mUserLru.remove(Integer.valueOf(userId));
18756                updateStartedUserArrayLocked();
18757
18758                // Clean up all state and processes associated with the user.
18759                // Kill all the processes for the user.
18760                forceStopUserLocked(userId, "finish user");
18761            }
18762
18763            // Explicitly remove the old information in mRecentTasks.
18764            removeRecentTasksForUserLocked(userId);
18765        }
18766
18767        for (int i=0; i<callbacks.size(); i++) {
18768            try {
18769                if (stopped) callbacks.get(i).userStopped(userId);
18770                else callbacks.get(i).userStopAborted(userId);
18771            } catch (RemoteException e) {
18772            }
18773        }
18774
18775        if (stopped) {
18776            mSystemServiceManager.cleanupUser(userId);
18777            synchronized (this) {
18778                mStackSupervisor.removeUserLocked(userId);
18779            }
18780        }
18781    }
18782
18783    @Override
18784    public UserInfo getCurrentUser() {
18785        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18786                != PackageManager.PERMISSION_GRANTED) && (
18787                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18788                != PackageManager.PERMISSION_GRANTED)) {
18789            String msg = "Permission Denial: getCurrentUser() from pid="
18790                    + Binder.getCallingPid()
18791                    + ", uid=" + Binder.getCallingUid()
18792                    + " requires " + INTERACT_ACROSS_USERS;
18793            Slog.w(TAG, msg);
18794            throw new SecurityException(msg);
18795        }
18796        synchronized (this) {
18797            int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18798            return getUserManagerLocked().getUserInfo(userId);
18799        }
18800    }
18801
18802    int getCurrentUserIdLocked() {
18803        return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18804    }
18805
18806    @Override
18807    public boolean isUserRunning(int userId, boolean orStopped) {
18808        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18809                != PackageManager.PERMISSION_GRANTED) {
18810            String msg = "Permission Denial: isUserRunning() 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            return isUserRunningLocked(userId, orStopped);
18819        }
18820    }
18821
18822    boolean isUserRunningLocked(int userId, boolean orStopped) {
18823        UserStartedState state = mStartedUsers.get(userId);
18824        if (state == null) {
18825            return false;
18826        }
18827        if (orStopped) {
18828            return true;
18829        }
18830        return state.mState != UserStartedState.STATE_STOPPING
18831                && state.mState != UserStartedState.STATE_SHUTDOWN;
18832    }
18833
18834    @Override
18835    public int[] getRunningUserIds() {
18836        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18837                != PackageManager.PERMISSION_GRANTED) {
18838            String msg = "Permission Denial: isUserRunning() from pid="
18839                    + Binder.getCallingPid()
18840                    + ", uid=" + Binder.getCallingUid()
18841                    + " requires " + INTERACT_ACROSS_USERS;
18842            Slog.w(TAG, msg);
18843            throw new SecurityException(msg);
18844        }
18845        synchronized (this) {
18846            return mStartedUserArray;
18847        }
18848    }
18849
18850    private void updateStartedUserArrayLocked() {
18851        int num = 0;
18852        for (int i=0; i<mStartedUsers.size();  i++) {
18853            UserStartedState uss = mStartedUsers.valueAt(i);
18854            // This list does not include stopping users.
18855            if (uss.mState != UserStartedState.STATE_STOPPING
18856                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18857                num++;
18858            }
18859        }
18860        mStartedUserArray = new int[num];
18861        num = 0;
18862        for (int i=0; i<mStartedUsers.size();  i++) {
18863            UserStartedState uss = mStartedUsers.valueAt(i);
18864            if (uss.mState != UserStartedState.STATE_STOPPING
18865                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18866                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18867                num++;
18868            }
18869        }
18870    }
18871
18872    @Override
18873    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18874        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18875                != PackageManager.PERMISSION_GRANTED) {
18876            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18877                    + Binder.getCallingPid()
18878                    + ", uid=" + Binder.getCallingUid()
18879                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18880            Slog.w(TAG, msg);
18881            throw new SecurityException(msg);
18882        }
18883
18884        mUserSwitchObservers.register(observer);
18885    }
18886
18887    @Override
18888    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18889        mUserSwitchObservers.unregister(observer);
18890    }
18891
18892    private boolean userExists(int userId) {
18893        if (userId == 0) {
18894            return true;
18895        }
18896        UserManagerService ums = getUserManagerLocked();
18897        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18898    }
18899
18900    int[] getUsersLocked() {
18901        UserManagerService ums = getUserManagerLocked();
18902        return ums != null ? ums.getUserIds() : new int[] { 0 };
18903    }
18904
18905    UserManagerService getUserManagerLocked() {
18906        if (mUserManager == null) {
18907            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18908            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18909        }
18910        return mUserManager;
18911    }
18912
18913    private int applyUserId(int uid, int userId) {
18914        return UserHandle.getUid(userId, uid);
18915    }
18916
18917    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18918        if (info == null) return null;
18919        ApplicationInfo newInfo = new ApplicationInfo(info);
18920        newInfo.uid = applyUserId(info.uid, userId);
18921        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18922                + info.packageName;
18923        return newInfo;
18924    }
18925
18926    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18927        if (aInfo == null
18928                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18929            return aInfo;
18930        }
18931
18932        ActivityInfo info = new ActivityInfo(aInfo);
18933        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18934        return info;
18935    }
18936
18937    private final class LocalService extends ActivityManagerInternal {
18938        @Override
18939        public void goingToSleep() {
18940            ActivityManagerService.this.goingToSleep();
18941        }
18942
18943        @Override
18944        public void wakingUp() {
18945            ActivityManagerService.this.wakingUp();
18946        }
18947
18948        @Override
18949        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18950                String processName, String abiOverride, int uid, Runnable crashHandler) {
18951            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18952                    processName, abiOverride, uid, crashHandler);
18953        }
18954    }
18955
18956    /**
18957     * An implementation of IAppTask, that allows an app to manage its own tasks via
18958     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18959     * only the process that calls getAppTasks() can call the AppTask methods.
18960     */
18961    class AppTaskImpl extends IAppTask.Stub {
18962        private int mTaskId;
18963        private int mCallingUid;
18964
18965        public AppTaskImpl(int taskId, int callingUid) {
18966            mTaskId = taskId;
18967            mCallingUid = callingUid;
18968        }
18969
18970        private void checkCaller() {
18971            if (mCallingUid != Binder.getCallingUid()) {
18972                throw new SecurityException("Caller " + mCallingUid
18973                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18974            }
18975        }
18976
18977        @Override
18978        public void finishAndRemoveTask() {
18979            checkCaller();
18980
18981            synchronized (ActivityManagerService.this) {
18982                long origId = Binder.clearCallingIdentity();
18983                try {
18984                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18985                    if (tr == null) {
18986                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18987                    }
18988                    // Only kill the process if we are not a new document
18989                    int flags = tr.getBaseIntent().getFlags();
18990                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18991                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18992                    removeTaskByIdLocked(mTaskId,
18993                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18994                } finally {
18995                    Binder.restoreCallingIdentity(origId);
18996                }
18997            }
18998        }
18999
19000        @Override
19001        public ActivityManager.RecentTaskInfo getTaskInfo() {
19002            checkCaller();
19003
19004            synchronized (ActivityManagerService.this) {
19005                long origId = Binder.clearCallingIdentity();
19006                try {
19007                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19008                    if (tr == null) {
19009                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19010                    }
19011                    return createRecentTaskInfoFromTaskRecord(tr);
19012                } finally {
19013                    Binder.restoreCallingIdentity(origId);
19014                }
19015            }
19016        }
19017
19018        @Override
19019        public void moveToFront() {
19020            checkCaller();
19021
19022            final TaskRecord tr;
19023            synchronized (ActivityManagerService.this) {
19024                tr = recentTaskForIdLocked(mTaskId);
19025                if (tr == null) {
19026                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19027                }
19028                if (tr.getRootActivity() != null) {
19029                    moveTaskToFrontLocked(tr.taskId, 0, null);
19030                    return;
19031                }
19032            }
19033
19034            startActivityFromRecentsInner(tr.taskId, null);
19035        }
19036
19037        @Override
19038        public int startActivity(IBinder whoThread, String callingPackage,
19039                Intent intent, String resolvedType, Bundle options) {
19040            checkCaller();
19041
19042            int callingUser = UserHandle.getCallingUserId();
19043            TaskRecord tr;
19044            IApplicationThread appThread;
19045            synchronized (ActivityManagerService.this) {
19046                tr = recentTaskForIdLocked(mTaskId);
19047                if (tr == null) {
19048                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19049                }
19050                appThread = ApplicationThreadNative.asInterface(whoThread);
19051                if (appThread == null) {
19052                    throw new IllegalArgumentException("Bad app thread " + appThread);
19053                }
19054            }
19055            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19056                    resolvedType, null, null, null, null, 0, 0, null, null,
19057                    null, options, callingUser, null, tr);
19058        }
19059
19060        @Override
19061        public void setExcludeFromRecents(boolean exclude) {
19062            checkCaller();
19063
19064            synchronized (ActivityManagerService.this) {
19065                long origId = Binder.clearCallingIdentity();
19066                try {
19067                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
19068                    if (tr == null) {
19069                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19070                    }
19071                    Intent intent = tr.getBaseIntent();
19072                    if (exclude) {
19073                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19074                    } else {
19075                        intent.setFlags(intent.getFlags()
19076                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19077                    }
19078                } finally {
19079                    Binder.restoreCallingIdentity(origId);
19080                }
19081            }
19082        }
19083    }
19084}
19085